home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / VTP031.ZIP;1 / VSTRINGU.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-12-30  |  92.0 KB  |  4,956 lines

  1. {
  2. ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕ
  3.  
  4. Visionix String (VStringu) Unit
  5.    Version 0.7
  6.  Copyright 1991,92,93 Visionix
  7.  ALL RIGHTS RESERVED
  8.  
  9. ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
  10.  
  11.  Revision history in reverse chronological order:
  12.  
  13.  Initials  Date      Comment
  14.  ƒƒƒƒƒƒƒƒ  ƒƒƒƒƒƒƒƒ  ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ
  15.  
  16.  jrt       11/28/93  Added CountWords, PosWord, GetWords.
  17.                      Changed TakeWord to TakeWords.
  18.                      Added PadLeft, PadRight, PadCenter.
  19.  
  20.  
  21.  jrt       11/02/93  First logged revision.  Move stuff in from VGENu;
  22.                      wrote string-list functions.
  23.  
  24. ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕ
  25. }
  26.  
  27. (*-
  28.  
  29. <Overview>
  30.  
  31. This unit implements a variety of functions for string allocation,
  32. usage, and management.  It also includes a set of advanced functions
  33. that implement a generic "string-list" mechanism which supports
  34. string arrays, string pointer arrays, link-list string arrays, and
  35. PChar arrays.
  36.  
  37.  
  38. <Interface>
  39.  
  40. -*)
  41.  
  42. Unit VStringu;
  43.  
  44. Interface
  45.  
  46. {$IFNDEF OS2}
  47.   {$DEFINE NOSTRINGS}
  48. {$ENDIF}
  49.  
  50. {$IFNDEF VER60}
  51.   {$DEFINE NOSTRINGS}
  52. {$ENDIF}
  53.  
  54. Uses
  55.  
  56. {$IFNDEF NOSTRINGS}
  57.   Strings,
  58. {$ENDIF}
  59.   VGenu,
  60.   VTypesu;
  61.  
  62. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  63.  
  64.  
  65. Const
  66.  
  67.   {---------------------------------}
  68.   { constants for string-list types }
  69.   {---------------------------------}
  70.  
  71.   cslStrings   = $0001;
  72.   cslPStrings  = $0002;
  73.   cslLLStrings = $0003;
  74.   cslPChars    = $0004;
  75.   cslLLPChars  = $0005;
  76.  
  77.  
  78. Type
  79.  
  80.   TPad  =  ( OnLeft, OnCenter, OnRight );
  81.  
  82.   {----------------------------------------}
  83.   { Types for array of pointers to strings }
  84.   {----------------------------------------}
  85.  
  86.   TPStrings = Array[1..1] of PSTRING;
  87.   PPStrings = ^TPStrings;
  88.  
  89.  
  90.   {---------------------------------------}
  91.   { Types for array of pointers to PChars }
  92.   {---------------------------------------}
  93.  
  94.   TPChars   = Array[1..1] of PCHAR;
  95.   PPChars   = ^TPChars;
  96.  
  97.  
  98.   TPointers = Array[1..1] of POINTER;
  99.   PPointers = ^TPointers;
  100.  
  101.   {--------------------------------}
  102.   { Types for link list of strings }
  103.   {--------------------------------}
  104.  
  105.   PLLStringNode = ^TLLStringNode;
  106.  
  107.   TLLStringNode = RECORD
  108.  
  109.     S        : STRING;
  110.     Next     : PLLStringNode;
  111.  
  112.   END;
  113.  
  114.   {-------------------------------}
  115.   { types for link list of pchars }
  116.   {-------------------------------}
  117.  
  118.   PLLPCharNode = ^TLLPCharNode;
  119.  
  120.   TLLPCharNode = RECORD
  121.  
  122.     S        : PChar;
  123.     Next     : PLLPCharNode;
  124.  
  125.   END;
  126.  
  127.   {----------------------}
  128.   { The String List type }
  129.   {----------------------}
  130.  
  131.   TStrList = RECORD
  132.  
  133.     Flags   : WORD;
  134.     Items   : WORD;
  135.     ItemLen : WORD;
  136.     SL      : POINTER;
  137.  
  138.   END;
  139.  
  140.   PStrList = ^TStrList;
  141.  
  142.  
  143. {----------------------}
  144. { Character and String }
  145. {----------------------}
  146.  
  147. Function  DeleteChars(            S              : STRING;
  148.                                   Ch             : CHAR         ) : STRING;
  149.  
  150. Function  UpperChar(              C              : CHAR         ) : CHAR;
  151.  
  152. Function  UpperString(            S              : STRING       ) : STRING;
  153.  
  154. Function  ProperString(           S              : STRING       ) : STRING;
  155.  
  156. Function  RepeatString(           S              : STRING;
  157.                                   Count          : BYTE         ) : STRING;
  158.  
  159.  
  160. Function  Pad(                    S              : STRING;
  161.                                   Len            : BYTE;
  162.                                   TypeOPad       : TPad;
  163.                                   Ch             : CHAR         ) : STRING;
  164.  
  165. Function  PadLeft(                S              : STRING;
  166.                                   Len            : BYTE;
  167.                                   Ch             : CHAR    ) : STRING;
  168.  
  169. Function  PadRight(               S              : STRING;
  170.                                   Len            : BYTE;
  171.                                   Ch             : CHAR    ) : STRING;
  172.  
  173. Function  PadCenter(              S              : STRING;
  174.                                   Len            : BYTE;
  175.                                   Ch             : CHAR    ) : STRING;
  176.  
  177. Function  Trim(                   S              : STRING;
  178.                                   Len            : BYTE;
  179.                                   TypeOTrim      : TPad         ) : STRING;
  180.  
  181. Function  TrimChar(               S              : STRING;
  182.                                   TypeOTrim      : TPad;
  183.                                   Ch             : CHAR         ) : STRING;
  184.  
  185. Function  LowerChar(              Ch             : CHAR         ) : CHAR;
  186.  
  187. Function  LowerString(            S              : STRING       ) : STRING;
  188.  
  189. Function  SR(                     Master,
  190.                                   LookFor,
  191.                                   ReplaceWith   : STRING        ) : STRING;
  192.  
  193. Function  GetNextParam(           SubS          : STRING;
  194.                                   S             : STRING        ) : STRING;
  195.  
  196. Function  GetNextParamEx(         SubS          : STRING;
  197.                                   S             : STRING;
  198.                                   Delimiter     : CHAR          ) : STRING;
  199.  
  200. Function  TakeNextParamEx(    Var S             : STRING;
  201.                                   Delimiter     : CHAR          ) : STRING;
  202.  
  203.  
  204. Function  GetParamName(           SubS          : STRING        ) : STRING;
  205.  
  206. Function  GetParamData(           SubS          : STRING        ) : STRING;
  207.  
  208. Function  PosBefore(              SubS           : STRING;
  209.                                   S              : STRING;
  210.                                   Index          : BYTE         ) : BYTE;
  211.  
  212. Function  PosAfter(               SubS           : STRING;
  213.                                   S              : STRING;
  214.                                   Index          : BYTE         ) : BYTE;
  215.  
  216. Function  PosEnd(                 Subs           : STRING;
  217.                                   S              : STRING       ) : BYTE;
  218.  
  219. Function  PosWord(                WordNum        : WORD;
  220.                                   S              : STRING       ) : BYTE;
  221.  
  222. Function  CopyStr(                S1             : STRING;
  223.                                   Index          : INTEGER;
  224.                                   Count          : INTEGER      ) : STRING;
  225.  
  226.  
  227. Function  TakeStr(            Var S1             : STRING;
  228.                                   Index          : INTEGER;
  229.                                   Count          : INTEGER   ) : STRING;
  230.  
  231.  
  232. Function  CopyOverStr(            S1             : STRING;
  233.                                   S2             : STRING;
  234.                                   Index          : INTEGER;
  235.                                   Count          : INTEGER      ) : STRING;
  236.  
  237. Function  OccurStr(               SubS           : STRING;
  238.                                   S              : STRING       ) : BYTE;
  239.  
  240. Function  GetWords(               S         : STRING;
  241.                                   NumWords  : WORD              ) : STRING;
  242.  
  243.  
  244. Function  TakeWords(          Var S              : STRING;
  245.                                   NumWords       : WORD         ) : STRING;
  246.  
  247. Function  CountWords(             S              : STRING       ) : BYTE;
  248.  
  249. Function  TakeQuote(          Var S              : STRING       ) : STRING;
  250.  
  251. Function  GetQuote(               S              : STRING       ) : STRING;
  252.  
  253.  
  254.  
  255.  
  256. Function  AddCommas(              S              : STRING       ) : STRING;
  257.  
  258. Procedure CRC16String(            S              : STRING;
  259.                               Var Result         : WORD;
  260.                                   NewResult      : BOOLEAN      );
  261.  
  262. Procedure CRC32String(            S              : STRING;
  263.                               Var Result         : LONGINT;
  264.                                   NewResult      : BOOLEAN      );
  265.  
  266. Function  WordWrap(           Var Stt            : STRING;
  267.                                   MaxWidth       : BYTE         ) : STRING;
  268.  
  269. Function  TruncAfter(             S              : STRING;
  270.                                   After          : STRING       ) : STRING;
  271.  
  272. Function  TruncAfterEnd(          S              : STRING;
  273.                                   After          : STRING       ) : STRING;
  274.  
  275.  
  276. Function  TruncAt(                S              : STRING;
  277.                                   At             : STRING       ) : STRING;
  278.  
  279. Function  TruncAtEnd(             S              : STRING;
  280.                                   At             : STRING       ) : STRING;
  281.  
  282. Function  PosBuf(                 SubS           : STRING;
  283.                               Var Buf;
  284.                                   Count          : WORD         ) : LONGINT;
  285.  
  286. Function  PosBufNoCase(           SubS           : STRING;
  287.                               Var Buf;
  288.                                   Count          : WORD         ) : LONGINT;
  289.  
  290.  
  291.  
  292. {--------------------------}
  293. { String Array Conversions }
  294. {--------------------------}
  295.  
  296. Procedure StrToArray(             S             : STRING;
  297.                               Var TheArray                      );
  298.  
  299. Function  ArrayToStr(         Var TheArray;
  300.                                   Len           : BYTE          ) : STRING;
  301.  
  302. Procedure StrToAsciiZ(            S             : STRING;
  303.                               Var AsciiZStr                     );
  304.  
  305. Function  AsciiZtoStr(        Var AsciiZStr                     ) : STRING;
  306.  
  307.  
  308.  
  309. (* NOT IMPLEMENTED YET...
  310.  
  311. {---------------------------------------------}
  312. { Generic numeric string to value conversions }
  313. {---------------------------------------------}
  314.  
  315. Function  StrToByteEx(            S            : STRING         ) : BYTE;
  316.  
  317. Function  StrToWordEx(            S            : STRING         ) : WORD;
  318.  
  319. Function  StrToIntEx(             S            : STRING         ) : INTEGER;
  320.  
  321. Function  StrToLongEx(            S            : STRING         ) : LONGINT;
  322.  
  323. *)
  324.  
  325.  
  326. {-----------------------}
  327. { heap-string functions }
  328. {-----------------------}
  329.  
  330. Function  VStrNew(                S             : STRING        ) : POINTER;
  331.  
  332. Function  VStrGet(                StringPtr     : PString       ) : STRING;
  333.  
  334.  
  335. Procedure VStrDispose(            PrevNewString : PString       );
  336.  
  337. {-----------------------}
  338. { string list functions }
  339. {-----------------------}
  340.  
  341. Function  VStrListNew(            Flags          : WORD;
  342.                                   NumItems       : INTEGER;
  343.                                   ItemLen        : WORD         ) : PStrList;
  344.  
  345. Procedure VStrListDispose(        SL             : PStrList     ) ;
  346.  
  347.  
  348. Function  VStrListGetPtr(         StrList        : PStrList;
  349.                                   StrNum         : INTEGER      ) : PSTRING;
  350.  
  351. Function  VStrListGetStr(         StrList        : PStrList;
  352.                                   StrNum         : INTEGER      ) : STRING;
  353.  
  354. Procedure VStrListPutStr(         StrList        : PStrList;
  355.                                   StrNum         : INTEGER;
  356.                                   StrToPut       : STRING       );
  357.  
  358. Function  VStrListGetPChar(       StrList        : PStrList;
  359.                                   StrNum         : INTEGER      ) : PChar;
  360.  
  361. Procedure VStrListPutPChar(       StrList        : PStrList;
  362.                                   StrNum         : INTEGER;
  363.                                   PCharToPut     : PChar        );
  364.  
  365. {----------------}
  366. { Misc functions }
  367. {----------------}
  368.  
  369. Function ColorFromString(        S              : STRING       ) : BYTE;
  370.  
  371.  
  372. Implementation
  373.  
  374.  
  375. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  376.  
  377.  
  378. (*-
  379.  
  380. [FUNCTION]
  381.  
  382. Function  DeleteChars(            S              : STRING;
  383.                                   Ch             : CHAR         ) : STRING;
  384.  
  385. [PARAMETERS]
  386.  
  387. S           Source String from which to Remove Characters
  388. Ch          Character to Search for and Delete from String
  389.  
  390. [RETURNS]
  391.  
  392. String "S" with all instances of character "Ch" removed.
  393.  
  394. [DESCRIPTION]
  395.  
  396. Deletes all instances of the specified character from the
  397. specified string.
  398.  
  399. [SEE-ALSO]
  400.  
  401. (none)
  402.  
  403. [EXAMPLE]
  404.  
  405. VAR
  406.   S : STRING;
  407.  
  408. BEGIN
  409.  
  410.   S := 'V-I-S-I-O-N-I-X';
  411.   S := DeleteChars( S, '-' );
  412.  
  413.   { S now equals 'VISIONIX' }
  414.  
  415. END;
  416.  
  417. -*)
  418.  
  419.  
  420.  
  421. Function  DeleteChars(            S              : STRING;
  422.                                   Ch             : CHAR         ) : STRING;
  423.  
  424.  
  425. Var
  426.  
  427.   Loopy : WORD;
  428.  
  429. BEGIN
  430.  
  431.   {-------------------------------------------------}
  432.   { Delete all occurances of the variable 'Ch' that }
  433.  
  434.   { are continaed within the variable 'S'.          }
  435.   {-------------------------------------------------}
  436.  
  437.   Loopy := 1;
  438.  
  439.   While ( Loopy <= Byte(S[0]) ) Do
  440.   BEGIN
  441.  
  442.     If (S[Loopy] = Ch) Then
  443.       Delete( S, Loopy, 1 )
  444.     Else
  445.       Inc( Loopy );
  446.  
  447.   END;
  448.  
  449.   DeleteChars := S;
  450.  
  451. END;   { Of DeleteChars }
  452.  
  453. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  454.  
  455.  
  456. (*-
  457.  
  458. [FUNCTION]
  459.  
  460. Function  UpperChar(              C              : CHAR         ) : CHAR;
  461.  
  462. [PARAMETERS]
  463.  
  464. C           The character to convert to Upper Case
  465.  
  466. [RETURNS]
  467.  
  468. The Character converted to Upper Case
  469.  
  470. [DESCRIPTION]
  471.  
  472. Converts a Character to Upper Case
  473.  
  474. [SEE-ALSO]
  475.  
  476. LowerChar
  477. UpperString
  478. LowerString
  479. ProperString
  480.  
  481. [EXAMPLE]
  482.  
  483. VAR
  484.   C : CHAR;
  485.  
  486. BEGIN
  487.  
  488.   C := UpperChar( 'a' );
  489.  
  490.   { C now equals 'A' }
  491.  
  492. END;
  493.  
  494. -*)
  495.  
  496. Function  UpperChar(              C              : CHAR         ) : CHAR;
  497.  
  498. BEGIN
  499.  
  500.   If ( C > #96 ) and ( C < #123 ) Then
  501.     C := Char( Byte( C ) XOR 32 );
  502.  
  503.   UpperChar := C;
  504.  
  505. END;
  506.  
  507. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  508.  
  509. (*-
  510.  
  511. [FUNCTION]
  512.  
  513. Function  UpperString(               S         : STRING  ) : STRING;
  514.  
  515. [PARAMETERS]
  516.  
  517. S           String to convert to Upper Case
  518.  
  519. [RETURNS]
  520.  
  521. String "S" in all Upper Case
  522.  
  523. [DESCRIPTION]
  524.  
  525. Converts an entire string to upper case.
  526.  
  527. [SEE-ALSO]
  528.  
  529. LowerString
  530. ProperString
  531. UpperChar
  532. LowerChar
  533.  
  534. [EXAMPLE]
  535.  
  536. VAR
  537.   S : STRING;
  538.  
  539. BEGIN
  540.  
  541.   S := 'This is a Test';
  542.   S := UpperString( S );
  543.  
  544.   { S = 'THIS IS A TEST' }
  545.  
  546. END;
  547.  
  548. -*)
  549.  
  550.  
  551. Function  UpperString(             S           : STRING  ) : STRING;
  552.  
  553. Var
  554.   PosS : WORD;
  555.  
  556. BEGIN
  557.  
  558.   For PosS := 1 to Byte(S[0]) Do
  559.     S[PosS] := UpperChar( S[PosS] );
  560.  
  561.   UpperString := S;
  562.  
  563. END;
  564.  
  565. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  566.  
  567. (*-
  568.  
  569. [FUNCTION]
  570.  
  571. Function  ProperString(               S         : STRING  ) : STRING;
  572.  
  573. [PARAMETERS]
  574.  
  575. S           String to Modify
  576.  
  577. [RETURNS]
  578.  
  579. String "S" with the First Characters of each word in Upper Case.
  580. All other characters in string "S" are made lower case.
  581.  
  582. [DESCRIPTION]
  583.  
  584. Converts the First Character of each Word in the String to
  585. Upper Case.  Converts all other characters to lower case.
  586.  
  587. [SEE-ALSO]
  588.  
  589. UpperString
  590. LowerString
  591. UpperChar
  592. LowerChar
  593.  
  594. [EXAMPLE]
  595.  
  596. VAR
  597.   S : STRING;
  598.  
  599. BEGIN
  600.  
  601.   S := 'joHN pAUl JOnEs';
  602.   S := ProperString( S );
  603.  
  604.   { S = 'John Paul Jones' }
  605.  
  606. END;
  607.  
  608. -*)
  609.  
  610. Function  ProperString(             S           : STRING  ) : STRING;
  611.  
  612. Var
  613.  
  614.   Upper  : BOOLEAN;
  615.   L1     : BYTE;
  616.  
  617. BEGIN
  618.  
  619.   Upper  := True;
  620.  
  621.   For L1 := 1 to Byte(S[0]) do
  622.   BEGIN
  623.  
  624.     If Upper Then
  625.     BEGIN
  626.  
  627.       If (IsAlpha(S[L1])) Then
  628.         Upper := False;
  629.  
  630.       S[L1] := UpCase(S[L1]);
  631.  
  632.     END
  633.     Else
  634.     BEGIN
  635.  
  636.       If NOT (IsAlphaNum(S[L1])) Then
  637.         Upper := True
  638.       Else
  639.         S[L1] := LowerChar(S[L1]);
  640.  
  641.     END;
  642.  
  643.   END;
  644.  
  645.   ProperString := S;
  646.  
  647. END;
  648.  
  649.  
  650. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  651.  
  652. (*-
  653.  
  654. [FUNCTION]
  655.  
  656. Function  RepeatString(           S              : STRING;
  657.                                   Count          : BYTE         ) : STRING;
  658.  
  659. [PARAMETERS]
  660.  
  661. s         string to repeat.
  662. count     number of times to repeat the string.
  663.  
  664. [RETURNS]
  665.  
  666. The string "s" repeated "count" times.
  667.  
  668. [DESCRIPTION]
  669.  
  670. This function will return a string which contains the string "s"
  671. repeated "count" times.
  672.  
  673. [SEE-ALSO]
  674.  
  675.  
  676. [EXAMPLE]
  677.  
  678.   T := RepeatString( 'Hello', 3 );
  679.  
  680.   { T now equals 'HelloHelloHello' }
  681.  
  682.   T := RepeatString( '-', 20 );
  683.  
  684.   {               12345678901234567890  }
  685.  
  686.   { t now equals '--------------------' }
  687.  
  688.  
  689. -*)
  690.  
  691.  
  692. Function  RepeatString(           S              : STRING;
  693.                                   Count          : BYTE         ) : STRING;
  694.  
  695. Var
  696.   Z : INTEGER;
  697.   RS: STRING;
  698. BEGIN
  699.  
  700.   RS := '';
  701.  
  702.   For Z:=1 to Count Do
  703.     RS := RS + S;
  704.  
  705.   RepeatString := RS;
  706.  
  707. END;
  708.  
  709.  
  710. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  711.  
  712. (*-
  713.  
  714. [FUNCTION]
  715.  
  716. Function  Pad(                       S         : STRING;
  717.                                      Len       : BYTE;
  718.                                      TypeOPad  : TPad;
  719.                                      Ch        : CHAR    ) : STRING;
  720.  
  721. [PARAMETERS]
  722.  
  723. S           The string to pad
  724. Len         The desired length of the resulting string
  725. TypeOPad    Type of pad operation you wish to perform
  726.  
  727.                  Left   Adds the pad character to the left of string
  728.                  Right  Adds the pad character to the right of string
  729.                  Center Adds the pad character equally on either side of
  730.                         string
  731. Ch          Character to pad with
  732.  
  733. [RETURNS]
  734.  
  735. The newly padded string based on "S"
  736.  
  737. [DESCRIPTION]
  738.  
  739. Pads the string "S" with the character "Ch" so that the string is
  740. "len" characters in length.  Three types of padding are supported:
  741. LEFT pads the left of the string, RIGHT pads the right, and CENTER
  742. pads on both sides.
  743.  
  744.   ++++++++++++++++++++++++++++++++++++++++++++++++++++
  745.   +                                                  +
  746.   + Note: Pad Left = Right Justified, and visa versa +
  747.   +                                                  +
  748.   ++++++++++++++++++++++++++++++++++++++++++++++++++++
  749.  
  750. [SEE-ALSO]
  751.  
  752. Trim
  753.  
  754. [EXAMPLE]
  755.  
  756. VAR
  757.   S : STRING;
  758.  
  759. BEGIN
  760.  
  761.   {----------------}
  762.   { CENTER padding }
  763.   {----------------}
  764.  
  765.   S := 'Hello, World';
  766.   S := Pad( S, 20, CENTER, '-' );
  767.  
  768.   { S now equals '----Hello, World----' }
  769.  
  770.   {--------------}
  771.   { LEFT padding }
  772.   {--------------}
  773.  
  774.   S := 'Hello, World';
  775.   S := Pad( S, 20, LEFT, '-' );
  776.  
  777.   { T now equals '--------Hello, World' }
  778.  
  779.   {---------------}
  780.   { RIGHT padding }
  781.   {---------------}
  782.  
  783.   S := 'Hello, World';
  784.   S := Pad( S, 20, RIGHT, '-' );
  785.  
  786.   { S now equals 'Hello, World--------' }
  787.  
  788. END;
  789.  
  790. -*)
  791.  
  792. Function  Pad(                     S           : STRING;
  793.                                    Len         : BYTE;
  794.                                    TypeOPad    : TPad;
  795.                                    Ch          : CHAR    ) : STRING;
  796.  
  797. BEGIN
  798.  
  799.   Case TypeOPad of
  800.  
  801.     ONLEFT :
  802.  
  803.       While ( Byte(S[0]) < Len ) Do
  804.         S := Ch + S;
  805.  
  806.     {---}
  807.  
  808.     ONCENTER :
  809.  
  810.       While ( Byte(S[0]) < Len ) Do
  811.       BEGIN
  812.  
  813.         S := S + Ch;
  814.  
  815.         If ( Byte(S[0]) < Len ) Then
  816.           S := Ch + S;
  817.  
  818.       END;
  819.  
  820.     {---}
  821.  
  822.     ONRIGHT :
  823.  
  824.       While ( Byte(S[0]) < Len) Do
  825.         S := S + Ch;
  826.  
  827.   END;
  828.  
  829.   Pad := S;
  830.  
  831. END;
  832.  
  833. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  834.  
  835.  
  836. Function  PadLeft(                 S           : STRING;
  837.                                    Len         : BYTE;
  838.                                    Ch          : CHAR    ) : STRING;
  839.  
  840. BEGIN
  841.  
  842.   PadLeft   := Pad( S, Len, onLeft, CH );
  843.  
  844. END;
  845.  
  846.  
  847.  
  848. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  849.  
  850.  
  851. Function  PadRight(                S           : STRING;
  852.                                    Len         : BYTE;
  853.                                    Ch          : CHAR    ) : STRING;
  854.  
  855. BEGIN
  856.  
  857.   PadRight   := Pad( S, Len, onRight, CH );
  858.  
  859. END;
  860.  
  861.  
  862. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  863.  
  864.  
  865. Function  PadCenter(               S           : STRING;
  866.                                    Len         : BYTE;
  867.                                    Ch          : CHAR    ) : STRING;
  868.  
  869. BEGIN
  870.  
  871.   PadCenter   := Pad( S, Len, onCenter, CH );
  872.  
  873. END;
  874.  
  875.  
  876.  
  877.  
  878. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  879.  
  880.  
  881.  
  882.  
  883.  
  884. (*-
  885.  
  886. [FUNCTION]
  887.  
  888. Function  Trim(                      S         : STRING;
  889.                                      Len       : BYTE;
  890.                                      TypeOTrim : TPad   ) : STRING;
  891.  
  892. [PARAMETERS]
  893.  
  894. S           The string to pad
  895. Len         The desired length of the resulting string
  896. TypeOTrim   Type of trim operation you wish to perform
  897.                  Left   Removes characters from the left of the string
  898.                  Right  Removes characters from the right of string
  899.                  Center Removed characters equally on either side of
  900.                         string
  901.  
  902. [RETURNS]
  903.  
  904. The newly trimmed string
  905.  
  906. [DESCRIPTION]
  907.  
  908. Trims the string "S".  If the "TypeOTrim" is LEFT, characters are
  909. removed from the left side of the string until the length of the
  910. string is "len".  If the "TypeOTrim" is RIGHT, characters are
  911. removed from the right side of the string until the length of the
  912. string is "len".  If the "TypeOTrim" is CENTER, characters are
  913. removed from both sides of the string until the length is "len".
  914.  
  915. Trim and Pad are inverse functions - one repairs the other.
  916.  
  917. [SEE-ALSO]
  918.  
  919. Pad
  920.  
  921. [EXAMPLE]
  922.  
  923. VAR
  924.   S : STRING;
  925.  
  926. BEGIN
  927.  
  928.   {-----------}
  929.   { Trim LEFT }
  930.   {-----------}
  931.  
  932.   S := Trim( '----Hello, World----', LEFT, 18 )
  933.  
  934.   { S now equals '--Hello, World----' }
  935.  
  936.   {------------}
  937.   { Trim RIGHT }
  938.   {------------}
  939.  
  940.   S := Trim( '----Hello, World----', RIGHT, 18 )
  941.  
  942.   { S now equals '----Hello, World--' }
  943.  
  944.   {-------------}
  945.   { Trim CENTER }
  946.   {-------------}
  947.  
  948.   S := Trim( '----Hello, World----', CENTER, 18 )
  949.  
  950.   { S now equals '---Hello, World---' }
  951.  
  952. END;
  953.  
  954. -*)
  955.  
  956.  
  957.  
  958. Function  Trim(                    S           : STRING;
  959.                                    Len         : BYTE;
  960.                                    TypeOTrim   : TPad    ) : STRING;
  961.  
  962. Var
  963.  
  964.   A : INTEGER;
  965.   B : INTEGER;
  966.  
  967. BEGIN
  968.  
  969.   A := 1;
  970.   B := Byte( S[0] );
  971.  
  972.   Case TypeOTrim of
  973.  
  974.     ONLEFT :
  975.  
  976.       BEGIN
  977.  
  978.         A := 1;
  979.         B := Byte(S[0]);
  980.  
  981.         While (A <= B) AND (B-A > Len) Do
  982.           Inc(A);
  983.  
  984.       END;
  985.  
  986.     {---}
  987.  
  988.     ONCENTER :
  989.  
  990.       BEGIN
  991.  
  992.         While (A <= B) AND (B-A > Len) Do
  993.           Inc(A);
  994.  
  995.         B := Len;
  996.  
  997. {        While (B >= A) AND (S[B] = Ch) Do }
  998. {          Dec(B);                         }
  999.  
  1000.       END;
  1001.  
  1002.     {---}
  1003.  
  1004.     ONRIGHT :
  1005.  
  1006.       BEGIN
  1007.         B := Len;
  1008.  
  1009. {        While (B >= A) AND (B-S[B] = Ch) Do }
  1010. {          Dec(B);                           }
  1011.  
  1012.       END;
  1013.  
  1014.   END;
  1015.  
  1016.   S    := Copy( S, A, Succ(B-A) );
  1017.   Trim := S;
  1018.  
  1019. END;
  1020.  
  1021. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1022.  
  1023. (*-
  1024.  
  1025. [FUNCTION]
  1026.  
  1027. Function  TrimChar(                  S         : STRING;
  1028.                                      TypeOTrim : TPad;
  1029.                                      Ch        : CHAR    ) : STRING;
  1030.  
  1031. [PARAMETERS]
  1032.  
  1033. S           The string to pad
  1034. TypeOTrim   Type of trim operation you wish to perform
  1035.                  Left   Removes a character from the left of the string
  1036.                  Right  Removes a character from the right of string
  1037.                  Center Removed a character equally on either side of
  1038.                         string
  1039. Ch          Character to trim from side.  This prevents trimming of part
  1040.             of the data which happens to also be of the same pad char.
  1041.  
  1042. [RETURNS]
  1043.  
  1044. The newly trimmed string
  1045.  
  1046. [DESCRIPTION]
  1047.  
  1048. Trims the string "S".  If the "TypeOTrim" is LEFT, all leading
  1049. occurances of the character "CH" are removed from the string.
  1050. If the "TypeOTrim" is RIGHT, all trailing occurances of the character
  1051. "CH" are removed from the string.  If the "TypeOTrim" is CENTER, all
  1052. leading and trailing occurances of the character "CH" are removed
  1053. from the string.
  1054.  
  1055. [SEE-ALSO]
  1056.  
  1057. Pad
  1058. Trim
  1059.  
  1060. [EXAMPLE]
  1061.  
  1062. VAR
  1063.   S : STRING;
  1064.  
  1065. BEGIN
  1066.  
  1067.   {-----------}
  1068.   { Trim LEFT }
  1069.   {-----------}
  1070.  
  1071.   S := TrimChar( '----Hello, World!----', LEFT, '-' )
  1072.  
  1073.   { S now equals 'Hello, World!----' }
  1074.  
  1075.   {------------}
  1076.   { Trim RIGHT }
  1077.   {------------}
  1078.  
  1079.   S := TrimChar( '----Hello, World!----', RIGHT, '-' )
  1080.  
  1081.   { S now equals '----Hello, World!' }
  1082.  
  1083.   {-------------}
  1084.   { Trim CENTER }
  1085.   {-------------}
  1086.  
  1087.   S := TrimChar( '----Hello, World!----', CENTER, '-' )
  1088.  
  1089.   { S now equals 'Hello, World!' }
  1090.  
  1091. END;
  1092.  
  1093. -*)
  1094.  
  1095.  
  1096. Function  TrimChar(                S           : STRING;
  1097.                                    TypeOTrim   : TPad;
  1098.                                    Ch          : CHAR    ) : STRING;
  1099.  
  1100. Var
  1101.  
  1102.   A : INTEGER;
  1103.   B : INTEGER;
  1104.  
  1105. BEGIN
  1106.  
  1107.   A := 1;
  1108.   B := Byte( S[0] );
  1109.  
  1110.   Case TypeOTrim of
  1111.  
  1112.     ONLEFT :
  1113.  
  1114.       BEGIN
  1115.  
  1116.         A := 1;
  1117.         B := Byte(S[0]);
  1118.  
  1119.         While (A <= B) AND (S[A] = Ch) Do
  1120.           Inc(A);
  1121.  
  1122.       END;
  1123.  
  1124.     {---}
  1125.  
  1126.     ONCENTER :
  1127.  
  1128.       BEGIN
  1129.  
  1130.         While (A <= B) AND (S[A] = Ch) Do
  1131.           Inc(A);
  1132.  
  1133.         While (B >= A) AND (S[B] = Ch) Do
  1134.           Dec(B);
  1135.  
  1136.       END;
  1137.  
  1138.     {---}
  1139.  
  1140.     ONRIGHT :
  1141.  
  1142.       BEGIN
  1143.  
  1144.         While (B >= A) AND (S[B] = Ch) Do
  1145.           Dec(B);
  1146.  
  1147.       END;
  1148.  
  1149.   END;
  1150.  
  1151.   S        := Copy( S, A, Succ(B-A) );
  1152.   TrimChar := S;
  1153.  
  1154. END;
  1155.  
  1156. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1157.  
  1158. (*-
  1159.  
  1160. [FUNCTION]
  1161.  
  1162. Function  LowerChar(                 Ch        : CHAR    ) : CHAR;
  1163.  
  1164. [PARAMETERS]
  1165.  
  1166. Ch          The character to convert to lowercase
  1167.  
  1168. [RETURNS]
  1169.  
  1170. A lowercase character
  1171.  
  1172. [DESCRIPTION]
  1173.  
  1174. Converts a the specified character to Lower Case.
  1175.  
  1176. [SEE-ALSO]
  1177.  
  1178. UpperChar
  1179. UpperString
  1180. LowerString
  1181.  
  1182. [EXAMPLE]
  1183.  
  1184. VAR
  1185.   C : CHAR;
  1186.  
  1187. BEGIN
  1188.  
  1189.   C := LowerChar( 'A' );
  1190.  
  1191.   { C = 'a' }
  1192.  
  1193. END;
  1194.  
  1195. -*)
  1196.  
  1197. Function  LowerChar(               Ch          : CHAR    ) : CHAR;
  1198.  
  1199. BEGIN
  1200.  
  1201.   If ( (Ch >= #65) AND (Ch <= #90) ) Then
  1202.     Ch := Char( Byte(Ch) OR 32 );
  1203.  
  1204.   LowerChar := Ch;
  1205.  
  1206. END;
  1207.  
  1208. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1209.  
  1210. (*-
  1211.  
  1212. [FUNCTION]
  1213.  
  1214. Function  LowerString(               S         : STRING  ) : STRING;
  1215.  
  1216. [PARAMETERS]
  1217.  
  1218. S           String to convert the lowercase
  1219.  
  1220. [RETURNS]
  1221.  
  1222. A lowercase string.
  1223.  
  1224. [DESCRIPTION]
  1225.  
  1226. Converts the string "S" to lower case.
  1227.  
  1228. [SEE-ALSO]
  1229.  
  1230. LowerChar
  1231. UpperChar
  1232. UpperString
  1233.  
  1234. [EXAMPLE]
  1235.  
  1236. VAR
  1237.   S : STRING;
  1238.  
  1239. BEGIN
  1240.  
  1241.   S := LowerString( 'Now is the TIME for AlL...' );
  1242.  
  1243.   { S now equals 'now is the time for all...' }
  1244.  
  1245. END;
  1246.  
  1247. -*)
  1248.  
  1249.  
  1250. Function  LowerString(             S           : STRING  ) : STRING;
  1251.  
  1252. Var
  1253.  
  1254.   I : BYTE;
  1255.  
  1256. BEGIN
  1257.  
  1258.   For I := 1 to Byte(S[0]) Do
  1259.  
  1260.     If ( (S[I] >= #65) AND (S[I] <= #90) ) Then
  1261.       S[I] := Char( Byte(S[I]) OR 32 );
  1262.  
  1263.   LowerString := S;
  1264.  
  1265. END;
  1266.  
  1267. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1268.  
  1269. (*-
  1270.  
  1271. [FUNCTION]
  1272.  
  1273. Function  SR(                        Master,
  1274.                                      LookFor,
  1275.                                      ReplaceWith : STRING) : STRING;
  1276.  
  1277. [PARAMETERS]
  1278.  
  1279. Master      String to perform the search and replace on
  1280. LookFor     String to look for in "Master"
  1281. ReplaceWith String to replace "LookFor" with.
  1282.  
  1283. [RETURNS]
  1284.  
  1285. A new string, based on "Master", that has all occurances of the
  1286. string "LookFor" replaced with "ReplaceWith".
  1287.  
  1288. [DESCRIPTION]
  1289.  
  1290. Using a given String, Searches for the sub-string "Lookfor" and replaces
  1291. all instances with of it with another sub-string, "ReplaceWith"
  1292.  
  1293. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1294. +                                                                 +
  1295. + Note: the SR function can be used to delete all occurances of a +
  1296. + substring within a string by specifying nothing ('') as the     +
  1297. + ReplaceWith parameter.                                          +
  1298. +                                                                 +
  1299. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1300.  
  1301. [SEE-ALSO]
  1302.  
  1303. (none)
  1304.  
  1305. [EXAMPLE]
  1306.  
  1307. VAR
  1308.   S : STRING;
  1309.  
  1310. BEGIN
  1311.  
  1312.   S := SR( 'Now is the time.  Now I Say!', 'Now', 'Tomorrow' );
  1313.  
  1314.   { S now equals 'Tomorrow is the time.  Tomorrow I Say!' }
  1315.  
  1316. END;
  1317.  
  1318. -*)
  1319.  
  1320.  
  1321. Function  SR(                      Master,
  1322.                                    LookFor,
  1323.                                    ReplaceWith : STRING  ) : STRING;
  1324.  
  1325. Var
  1326.  
  1327.   Z : INTEGER;
  1328.  
  1329. BEGIN
  1330.  
  1331.   Z := Pos( LookFor, Master );
  1332.  
  1333.   While (Z > 0) Do
  1334.   BEGIN
  1335.  
  1336.     Delete( Master, Z, Byte(LookFor[0]) );
  1337.     Insert( ReplaceWith, Master, Z );
  1338.     Z := Pos( LookFor, Master );
  1339.  
  1340.   END;
  1341.  
  1342.   SR := Master;
  1343.  
  1344. END;
  1345.  
  1346. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1347.  
  1348. (*-
  1349.  
  1350. [FUNCTION]
  1351.  
  1352. Function  GetNextParam(              SubS      : STRING;
  1353.                                      S         : STRING  ) : STRING;
  1354.  
  1355. [PARAMETERS]
  1356.  
  1357. Subs        Sub-string that preceeds up to the parameter to get
  1358. S           Parameter list to get the next parameter from
  1359.  
  1360. [RETURNS]
  1361.  
  1362. The next Parameter following the given Starting Parameter Sub-String
  1363.  
  1364. [DESCRIPTION]
  1365.  
  1366. This function takes a string of text parameters (delimited by commas) and
  1367. searches for the parameter following the one provided.  The parameter may
  1368. be a single symbol or have a value following it (using an equals sign as
  1369. in the examples below).
  1370. The following Examples illustrate usage:
  1371.   Ex #1 : GetNextParam( 'B=C', 'A=B,B=C,C=D,D=10' ) = 'C=D'
  1372.   Ex #2 : GetNextParam( '',    'A=B,B=C,C=D,D=10' ) = 'A=B'
  1373.   Ex #3 : GetNextParam( 'B',   'A=B,B=C,C=D,D=10' ) = 'C=D'
  1374.  
  1375. [SEE-ALSO]
  1376.  
  1377. GetNextParamEx
  1378. GetParamName
  1379. GetParamData
  1380.  
  1381. [EXAMPLE]
  1382.  
  1383. VAR
  1384.   S,T : STRING;
  1385.  
  1386. BEGIN
  1387.  
  1388.   S := 'Ground=Brown,Sky=Blue,Trees=Green,World=Round';
  1389.   T := '';
  1390.  
  1391.   REPEAT
  1392.  
  1393.     S := GetNextParam( T, S );
  1394.     WriteLn( 'T="', T, '"' );
  1395.  
  1396.   UNTIL T = '';
  1397.  
  1398.   {----------------}
  1399.   { Output:        }
  1400.   {                }
  1401.   { "Ground=Brown" }
  1402.   { "Sky=Blue"     }
  1403.   { "Trees=Green"  }
  1404.   { "World=Round"  }
  1405.   {----------------}
  1406.  
  1407.   S := 'Ground=Brown,Sky=Blue,Trees=Green,World=Round';
  1408.   T := GetNextParam( 'Sky', S );
  1409.  
  1410.   { T = 'Trees=Green' }
  1411.  
  1412. END;
  1413.  
  1414. -*)
  1415.  
  1416.  
  1417. Function  GetNextParam(            SubS        : STRING;
  1418.                                    S           : STRING  ) : STRING;
  1419.  
  1420. Var
  1421.  
  1422.   Index : INTEGER;
  1423.   Count : BYTE;
  1424.  
  1425. BEGIN
  1426.  
  1427.   Count  := 0;
  1428.  
  1429.   If (Byte(SubS[0]) = 0) Then
  1430.     Index := 1
  1431.   Else
  1432.     Index := Pos( SubS, S );
  1433.  
  1434.   If ( Byte(SubS[0]) > 0 ) AND
  1435.      ( SubS[1] <> ',' ) AND
  1436.      ( Index > 0 ) Then
  1437.   BEGIN
  1438.  
  1439.     Repeat
  1440.       Inc( Index );
  1441.     Until ( Index >= Byte(S[0]) ) OR ( S[Index] = ',' );
  1442.     Inc( Index );
  1443.  
  1444.   END;
  1445.  
  1446.   While ( Index+Count < Byte(S[0]) ) AND ( S[Index+Count] <> ',' ) AND
  1447.         ( Index > 0 ) Do
  1448.     Inc( Count );
  1449.  
  1450.   If Index + Count = Byte(S[0]) Then
  1451.     Inc(Count);
  1452.  
  1453.   GetNextParam := Copy( S, Index, Count );
  1454.  
  1455. END;
  1456.  
  1457. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1458.  
  1459. (*-
  1460.  
  1461. [FUNCTION]
  1462.  
  1463. Function  GetNextParamEx(            SubS      : STRING;
  1464.                                      S         : STRING;
  1465.                                      Delimiter : CHAR    ) : STRING;
  1466.  
  1467. [PARAMETERS]
  1468.  
  1469. Subs        Sub-String that preceeds up to the parameter to get
  1470. S           Parameter list to get the next parameter from
  1471. Delimiter   Sub-String Separator Character
  1472.  
  1473. [RETURNS]
  1474.  
  1475. The next Parameter following the given Starting Parameter Sub-String.
  1476.  
  1477. [DESCRIPTION]
  1478.  
  1479. This function takes a string of text parameters (delimited by the
  1480. specified "Delimiter") and searches for the parameter following the one
  1481. provided.  The parameter may be a single symbol or have a value
  1482. following it (using an equals sign as in the examples below).
  1483.  
  1484. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1485. +                                                                 +
  1486. + Note:  This function is an EXtended version of the GetNextParam +
  1487. + function, with the extension of being able to specify the       +
  1488. + character that seperates the parameters of a parameter string.  +
  1489. +                                                                 +
  1490. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1491.  
  1492. [SEE-ALSO]
  1493.  
  1494. GetNextParam
  1495. GetParamName
  1496. GetParamData
  1497.  
  1498. [EXAMPLE]
  1499.  
  1500. VAR
  1501.   S : STRING;
  1502.  
  1503. BEGIN
  1504.  
  1505.   {------------}
  1506.   { Example #1 }
  1507.   {------------}
  1508.  
  1509.   S := GetNextParam( '',
  1510.                      'Ground=Brown,Sky=Blue|Trees=Green,World=Round',
  1511.                      '|' )
  1512.  
  1513.   { S now equals 'Ground=Brown,Sky=Blue' }
  1514.  
  1515.   {------------}
  1516.   { Example #2 }
  1517.   {------------}
  1518.  
  1519.   S := GetNextParam( 'Ground=Brown,Sky=Blue',
  1520.                      'Ground=Brown,Sky=Blue|Trees=Green,World=Round',
  1521.                      '|' )
  1522.  
  1523.   { S now equals 'Trees=Green,World=Round' }
  1524.  
  1525. END;
  1526.  
  1527. -*)
  1528.  
  1529.  
  1530. Function  GetNextParamEx(          SubS        : STRING;
  1531.                                    S           : STRING;
  1532.                                    Delimiter   : CHAR    ) : STRING;
  1533.  
  1534. Var
  1535.  
  1536.   Index : INTEGER;
  1537.   Count : BYTE;
  1538.  
  1539. BEGIN
  1540.  
  1541.   Count  := 0;
  1542.  
  1543.   If (Byte(SubS[0]) = 0) Then
  1544.     Index := 1
  1545.   Else
  1546.     Index := Pos( SubS, S );
  1547.  
  1548.   If ( Byte(SubS[0]) > 0 ) AND
  1549.      ( SubS[1] <> Delimiter ) AND
  1550.      ( Index > 0 ) Then
  1551.   BEGIN
  1552.  
  1553.     Repeat
  1554.       Inc( Index );
  1555.     Until ( Index >= Byte(S[0]) ) OR ( S[Index] = Delimiter );
  1556.     Inc( Index );
  1557.  
  1558.   END;
  1559.  
  1560.   While ( Index+Count < Byte(S[0]) ) AND
  1561.         ( S[Index+Count] <> Delimiter ) AND
  1562.         ( Index > 0 ) Do
  1563.     Inc( Count );
  1564.  
  1565.   If Index + Count = Byte(S[0]) Then
  1566.     Inc(Count);
  1567.  
  1568.   GetNextParamEx := Copy( S, Index, Count );
  1569.  
  1570. END;
  1571.  
  1572. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1573.  
  1574.  
  1575. Function  TakeNextParamEx(    Var S             : STRING;
  1576.                                   Delimiter     : CHAR          ) : STRING;
  1577.  
  1578.  
  1579. Var
  1580.  
  1581.   Z : INTEGER;
  1582.  
  1583. BEGIN
  1584.  
  1585.  
  1586.   If S='' THen
  1587.     TakeNextParamEx := ''
  1588.   Else
  1589.   BEGIN
  1590.  
  1591.     Z := Pos( Delimiter, S );
  1592.  
  1593.     IF Z=0 Then
  1594.       Z := Length( S )+1;
  1595.  
  1596.     TakeNextParamEx := TakeStr( S, 1, Z-1 );
  1597.  
  1598.     Delete( S, 1, 1 );
  1599.  
  1600.   END;
  1601.  
  1602. END;
  1603.  
  1604.  
  1605. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1606.  
  1607.  
  1608. (*-
  1609.  
  1610. [FUNCTION]
  1611.  
  1612. Function  GetParamName(              SubS      : STRING  ) : STRING;
  1613.  
  1614. [PARAMETERS]
  1615.  
  1616. SubS        Source Parameter String
  1617.  
  1618. [RETURNS]
  1619.  
  1620. Parameter Field Name from Source String
  1621.  
  1622. [DESCRIPTION]
  1623.  
  1624. This function returns the parameter name portion of a parameter string.
  1625. The parameter name portion is defined to be "the portion preceding the
  1626. equal sign."
  1627.  
  1628. [SEE-ALSO]
  1629.  
  1630. GetNextParamEx
  1631. PosNextData
  1632.  
  1633. [EXAMPLE]
  1634.  
  1635. VAR
  1636.   S : STRING;
  1637.  
  1638. BEGIN
  1639.  
  1640.   S := GetParamName( 'Trees=Green' );
  1641.  
  1642.   { S now equals 'Trees' }
  1643.  
  1644. END;
  1645.  
  1646. -*)
  1647.  
  1648.  
  1649. Function  GetParamName(            SubS        : STRING  ) : STRING;
  1650.  
  1651. Var
  1652.  
  1653.   PosField : INTEGER;
  1654.  
  1655. BEGIN
  1656.  
  1657.   PosField := Pos( '=', SubS );
  1658.  
  1659.   If PosField <> 0 Then
  1660.     GetParamName := Copy( SubS, 1, Pred(PosField) )
  1661.   Else
  1662.     GetParamName := SubS;
  1663.  
  1664. END;
  1665.  
  1666. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1667.  
  1668. (*-
  1669.  
  1670. [FUNCTION]
  1671.  
  1672. Function  GetParamData(               SubS      : STRING  ) : STRING;
  1673.  
  1674. [PARAMETERS]
  1675.  
  1676. SubS        Source Parameter String with Value
  1677.  
  1678. [RETURNS]
  1679.  
  1680. Parameter Field Value from Source String
  1681.  
  1682. [DESCRIPTION]
  1683.  
  1684. This function returns the data portion of a parameter string.  The
  1685. data portion is defined as "the portion following the equal sign".
  1686.  
  1687. [SEE-ALSO]
  1688.  
  1689. GetNextParamEx
  1690. GetParamName
  1691.  
  1692. [EXAMPLE]
  1693.  
  1694. VAR
  1695.   S : STRING;
  1696.  
  1697. BEGIN
  1698.  
  1699.   S := GetParamData( 'Trees=Green' );
  1700.  
  1701.   { T now equals 'Green' }
  1702.  
  1703. END;
  1704.  
  1705. -*)
  1706.  
  1707. Function  GetParamData(             SubS        : STRING  ) : STRING;
  1708.  
  1709. Var
  1710.  
  1711.   PosSub : INTEGER;
  1712.  
  1713. BEGIN
  1714.  
  1715.   PosSub := Pos( '=', SubS );
  1716.  
  1717.   If PosSub <> 0 Then
  1718.     GetParamData := TrimChar(
  1719.                       Copy( SubS, Succ(PosSub), Byte(SubS[0]) - PosSub ),
  1720.                       ONCENTER,
  1721.                       ' '       )
  1722.   Else
  1723.     GetParamData := '';
  1724.  
  1725. END;
  1726.  
  1727. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1728.  
  1729.  
  1730. (*-
  1731.  
  1732. [FUNCTION]
  1733.  
  1734. Function  PosBefore(                 SubS      : STRING;
  1735.                                      S         : STRING;
  1736.                                      Index     : BYTE    ) : BYTE;
  1737.  
  1738. [PARAMETERS]
  1739.  
  1740. SubS        Sub-String to locate
  1741. S           Source String to search
  1742. Index       Limiting Search Index
  1743.  
  1744. [RETURNS]
  1745.  
  1746. Index into Source String where Sub-String was Found
  1747.  
  1748. [DESCRIPTION]
  1749.  
  1750. This function is much like the standard POS function.  PosBefore
  1751. differs in that you can specify the "Index" at which to end the search.
  1752. If the specified "SubS"tring occurs before "Index", it's position will
  1753. be returned.  If it occurs after the "Index", or if it does not occur
  1754. in "S", the function will return a 0.
  1755.  
  1756. [SEE-ALSO]
  1757.  
  1758. PosNext
  1759. PosAfter
  1760. PosEnd
  1761.  
  1762. [EXAMPLE]
  1763.  
  1764. VAR
  1765.   S : STRING;
  1766.  
  1767. BEGIN
  1768.  
  1769.   {------------}
  1770.   { Example #1 }
  1771.   {------------}
  1772.  
  1773.   X := PosBefore( 'World',
  1774.                   'Hello, World!  Whats up?',
  1775.                   11  );
  1776.  
  1777.   (X now equals 0, since the string 'World' does not completely occur
  1778.    before the 11th character in the main string)
  1779.  
  1780.   {------------}
  1781.   { Example #2 }
  1782.   {------------}
  1783.  
  1784.   X := PosBefore( 'World',
  1785.                   'Hello, World!  Whats up?',
  1786.                   20  );
  1787.  
  1788.  
  1789.   {------------------------------------------------------------}
  1790.   { S now equals 8, since the string 'World' occurs before the }
  1791.   { 20th character in the main string, at the 8th character    }
  1792.   {------------------------------------------------------------}
  1793.  
  1794. END;
  1795.  
  1796. -*)
  1797.  
  1798. Function  PosBefore(                 SubS      : STRING;
  1799.                                      S         : STRING;
  1800.                                      Index     : BYTE    ) : BYTE;
  1801.  
  1802. Var
  1803.  
  1804.   P : BYTE;
  1805.  
  1806. BEGIN
  1807.  
  1808.   P := Pos(SubS, S);
  1809.  
  1810.   If P + Pred(Byte(SubS[0])) > Index Then
  1811.     P := 0;
  1812.  
  1813.   PosBefore := P;
  1814.  
  1815. END;
  1816.  
  1817. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1818.  
  1819.  
  1820. (*-
  1821.  
  1822. [FUNCTION]
  1823.  
  1824. Function  PosAfter(                  SubS      : STRING;
  1825.                                      S         : STRING;
  1826.                                      Index     : BYTE    ) : BYTE;
  1827.  
  1828. [PARAMETERS]
  1829.  
  1830. SubS        Sub-String to locate
  1831. S           Source String to search
  1832. Index       Starting Search Index
  1833.  
  1834. [RETURNS]
  1835.  
  1836. Index into Source String where Sub-String was Found
  1837.  
  1838. [DESCRIPTION]
  1839.  
  1840. This function is much like the standard POS function.  PosAfter
  1841. differs in that you can specify the "Index" at which to start the search.
  1842. If the specified "SubS"tring occurs after "Index", it's position will
  1843. be returned.  If it occurs before the "Index", or if it does not occur
  1844. in "S", the function will return a 0.
  1845.  
  1846. [SEE-ALSO]
  1847.  
  1848. Pos
  1849. PosNext
  1850. PosBefore
  1851. PosEnd
  1852.  
  1853. [EXAMPLE]
  1854.  
  1855. VAR
  1856.   B : BYTE;
  1857.  
  1858. BEGIN
  1859.  
  1860.   B := PosAfter( 'Hello', 'Excuse me, but: Hello, World!  Whats up?', 20 );
  1861.  
  1862.   {-----------------------------------------------------------}
  1863.   { B now equals 0, since the complete substring "Hello" does }
  1864.   { not occur after the 20th character of the main string     }
  1865.   {-----------------------------------------------------------}
  1866.  
  1867. END;
  1868.  
  1869. -*)
  1870.  
  1871. Function  PosAfter(                  SubS      : STRING;
  1872.                                      S         : STRING;
  1873.                                      Index     : BYTE    ) : BYTE;
  1874.  
  1875. Var
  1876.  
  1877.   P : BYTE;
  1878.  
  1879. BEGIN
  1880.  
  1881.   P := Pos(SubS, CopyStr(S, Index, Byte(S[0]) - Pred(Index)));
  1882.  
  1883.   If (P > 0) Then
  1884.     Inc(P, Pred(Index));
  1885.  
  1886.   PosAfter := P;
  1887.  
  1888. END;
  1889.  
  1890. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1891.  
  1892. (*-
  1893.  
  1894. [FUNCTION]
  1895.  
  1896. Function   PosEnd(                   Subs      : STRING;
  1897.                                      S         : STRING  ) : BYTE;
  1898.  
  1899. [PARAMETERS]
  1900.  
  1901. SubS        Sub-String
  1902. S           Source String to Search
  1903.  
  1904. [RETURNS]
  1905.  
  1906. Index into Source String where Sub-String was Found
  1907.  
  1908. [DESCRIPTION]
  1909.  
  1910. This function is much like the standard POS function.  PosEnd differs
  1911. in that the search is started from the end of the string instead of
  1912. the beggining.  This allows you to get the position of the LAST
  1913. occurance of a substring within a string.
  1914.  
  1915. This function will return the position of the last occurance of the
  1916. sub-string within the string.  If the sub-string is not found within
  1917. the string, this function will return 0.
  1918.  
  1919. [SEE-ALSO]
  1920.  
  1921. Pos
  1922. PosNext
  1923. PosBefore
  1924. PosAfter
  1925.  
  1926. [EXAMPLE]
  1927.  
  1928. VAR
  1929.   B : BYTE;
  1930.  
  1931. BEGIN
  1932.   B := PosEnd( 'Hello', 'Hello! Again I say Hello, World!  Whats up?' );
  1933.  
  1934.   { B = 20 }
  1935.  
  1936. END;
  1937.  
  1938. -*)
  1939.  
  1940. Function   PosEnd(                   Subs      : STRING;
  1941.                                      S         : STRING  ) : BYTE;
  1942.  
  1943. Var
  1944.  
  1945.   Z     : BYTE;
  1946.   Found : BOOLEAN;
  1947.  
  1948. BEGIN
  1949.  
  1950.   Z := Length( S );
  1951.  
  1952.   Found := FALSE;
  1953.  
  1954.   While (Z>0) and (Not Found) Do
  1955.   BEGIN
  1956.  
  1957.     If S[Z] = SubS[1] Then
  1958.     BEGIN
  1959.  
  1960.       If Copy( S, Z, Length(Subs) ) = Subs Then
  1961.         Found := TRUE
  1962.       Else
  1963.         Dec( Z );
  1964.  
  1965.     END
  1966.     ELSE
  1967.       Dec( Z );
  1968.  
  1969.   END;
  1970.  
  1971.   PosEnd := Z;
  1972.  
  1973. END;
  1974.  
  1975. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  1976.  
  1977. (*-
  1978.  
  1979. [FUNCTION]
  1980.  
  1981. Function  PosWord(                WordNum        : WORD;
  1982.                                   S              : STRING       ) : BYTE;
  1983.  
  1984. [PARAMETERS]
  1985.  
  1986. WordNum     Word to get the starting position of
  1987. S           Source String to Search
  1988.  
  1989. [RETURNS]
  1990.  
  1991. Index into Source String where word # "wordnum" starts
  1992.  
  1993. [DESCRIPTION]
  1994.  
  1995. This function returns the position within the string "s" at which
  1996. the specified word # "wordnum" starts.  If "wordum" number of words
  1997. can not be found in the string, this function will return 0.
  1998.  
  1999. [SEE-ALSO]
  2000.  
  2001. Pos
  2002. PosNext
  2003. PosBefore
  2004. PosAfter
  2005.  
  2006. [EXAMPLE]
  2007.  
  2008. VAR
  2009.   B : BYTE;
  2010.  
  2011. BEGIN
  2012.                    {123456789012345678012345678901234567}
  2013.  
  2014.   B := PosWord( 3, 'Now is the time for all good people.');
  2015.  
  2016.   { B = 8 }
  2017.  
  2018. END;
  2019.  
  2020. -*)
  2021.  
  2022.  
  2023. Function  PosWord(                WordNum        : WORD;
  2024.                                   S              : STRING       ) : BYTE;
  2025.  
  2026. Var
  2027.  
  2028.   EndOfs  : BYTE;
  2029.   LastOfs : BYTE;
  2030.   CurOfs  : BYTE;
  2031.  
  2032. BEGIN
  2033.  
  2034.   { get rid of leading/trailing spaces and add a terminating space }
  2035.  
  2036.   S := TrimChar( S, OnCenter, ' ' )+' ';
  2037.  
  2038.   { loop through the string }
  2039.  
  2040.   EndOfs  := 0;
  2041.   LastOfs := 1;
  2042.   CurOfs  := 1;
  2043.  
  2044.   While ( EndOfs <= Length( S ) ) and
  2045.         ( WordNum >0           ) Do
  2046.   BEGIN
  2047.  
  2048.     Inc( EndOfs );
  2049.  
  2050.     If (S[EndOfs]=' ') Then
  2051.     BEGIN
  2052.       Dec( WordNum );
  2053.       CurOfs := LastOfs;
  2054.       LastOfs := Succ( EndOfs );
  2055.     END;
  2056.  
  2057.   END;
  2058.  
  2059.   { if we didnt find all the words, return a 0 }
  2060.  
  2061.   If WordNum<>0 Then
  2062.     PosWord := 0
  2063.   Else
  2064.     PosWord := CurOfs;
  2065.  
  2066. END;
  2067.  
  2068.  
  2069. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2070.  
  2071.  
  2072.  
  2073. (*-
  2074.  
  2075. [FUNCTION]
  2076.  
  2077. Function  CopyStr(                   S1        : STRING;
  2078.                                      Index     : INTEGER;
  2079.                                      Count     : INTEGER ) : STRING;
  2080.  
  2081. [PARAMETERS]
  2082.  
  2083. S1          Source String to Copy from
  2084. Index       Position in Source String to Start Copy at
  2085. Count       Number of Characters to Copy
  2086.  
  2087. [RETURNS]
  2088.  
  2089. The specified sub-string, starting at "index" and going for "count"
  2090. bytes.
  2091.  
  2092. [DESCRIPTION]
  2093.  
  2094. This function is the same as the standard Turbo Pascal "Copy" Command.
  2095.  
  2096. [SEE-ALSO]
  2097.  
  2098. CopyOverStr
  2099.  
  2100. [EXAMPLE]
  2101.  
  2102. VAR
  2103.   S : STRING;
  2104.  
  2105. BEGIN
  2106.  
  2107.   S := CopyStr( 'The Color is Blue.', 14, 4 );
  2108.  
  2109.   { S now equals "Blue" }
  2110.  
  2111. END;
  2112.  
  2113. -*)
  2114.  
  2115.  
  2116.  
  2117. Function  CopyStr(                   S1        : STRING;
  2118.                                      Index     : INTEGER;
  2119.                                      Count     : INTEGER ) : STRING;
  2120.  
  2121. Var
  2122.  
  2123.   S2 : STRING;
  2124.  
  2125. BEGIN
  2126.  
  2127.   If ( Count + Index ) > Byte( S1[0] ) Then
  2128.   BEGIN
  2129.  
  2130.     Count := Byte(S1[0]) - Index;
  2131.     Inc( Count );
  2132.  
  2133.   END;
  2134.  
  2135.   Move( S1[Index], S2[1], Count );
  2136.   S2[0] := Char( Count );
  2137.   CopyStr := S2;
  2138.  
  2139. END;
  2140.  
  2141.  
  2142. (*-
  2143.  
  2144. [FUNCTION]
  2145.  
  2146. Function  TakeStr(                   S1        : STRING;
  2147.                                      Index     : INTEGER;
  2148.                                      Count     : INTEGER ) : STRING;
  2149.  
  2150. [PARAMETERS]
  2151.  
  2152. S1          Source String to take from
  2153. Index       Position in Source String to Start take at
  2154. Count       Number of Characters to take
  2155.  
  2156. [RETURNS]
  2157.  
  2158. The specified sub-string, starting at "index" and going for "count"
  2159. bytes.
  2160.  
  2161. [DESCRIPTION]
  2162.  
  2163. This function is the similar to the standard Turbo Pascal "Copy"
  2164. Command.  It differs in that it returns the sub-string also removes
  2165. the sub-string from the original string.
  2166.  
  2167. [SEE-ALSO]
  2168.  
  2169. CopyOverStr
  2170.  
  2171. [EXAMPLE]
  2172.  
  2173. VAR
  2174.   S : STRING;
  2175.  
  2176. BEGIN
  2177.  
  2178.   T := 'The Color is Blue.';
  2179.  
  2180.   S := TakeStr( T, 14, 4 );
  2181.  
  2182.   { S now equals "Blue" }
  2183.  
  2184.   { t now equals "The Color is." }
  2185.  
  2186. END;
  2187.  
  2188. -*)
  2189.  
  2190.  
  2191.  
  2192.  
  2193.  
  2194. Function TakeStr(                Var S1        : STRING;
  2195.                                      Index     : INTEGER;
  2196.                                      Count     : INTEGER   ) : STRING;
  2197.  
  2198. BEGIN
  2199.  
  2200.   TakeStr := CopyStr( S1, Index, Count );
  2201.  
  2202.   Delete( S1, Index, Count );
  2203.  
  2204. END;
  2205.  
  2206.  
  2207. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2208.  
  2209. (*-
  2210.  
  2211. [FUNCTION]
  2212.  
  2213. Function  CopyOverStr(               S1        : STRING;
  2214.                                      S2        : STRING;
  2215.                                      Index     : INTEGER;
  2216.                                      Count     : INTEGER  ) : STRING;
  2217.  
  2218. [PARAMETERS]
  2219.  
  2220. S1          string that will be overwritten into S2
  2221. S2          original string
  2222. Index       Position in the original string (s2) to overwrite at
  2223. Count       Number of Characters to overwrite
  2224.  
  2225. [RETURNS]
  2226.  
  2227. String "s2" with string "s1" overwritten at "index" for "count"
  2228. characters.
  2229.  
  2230. [DESCRIPTION]
  2231.  
  2232. This function takes the string "S1" and uses it to overwrite
  2233. a portion of "S2", starting at the specified "index" and for
  2234. the specified "count" of number of characters.
  2235.  
  2236. [SEE-ALSO]
  2237.  
  2238. CopyStr
  2239.  
  2240. [EXAMPLE]
  2241.  
  2242. VAR
  2243.   S : STRING;
  2244.  
  2245. BEGIN
  2246.  
  2247.   S := 'The Color is Cyan on gold.';
  2248.   S := CopyOverStr( S, 'Blue', 14, 4 );
  2249.  
  2250.   { S now equals "The Color is Blue on gold." }
  2251.  
  2252. END;
  2253.  
  2254. -*)
  2255.  
  2256. Function  CopyOverStr(               S1        : STRING;
  2257.                                      S2        : STRING;
  2258.                                      Index     : INTEGER;
  2259.                                      Count     : INTEGER  ) : STRING;
  2260.  
  2261. Var
  2262.  
  2263.   NewLen : WORD;
  2264.   S3     : STRING;
  2265.  
  2266. BEGIN
  2267.  
  2268.   NewLen := Index + Count;
  2269.  
  2270.   If NewLen > 255 Then
  2271.     NewLen := 255;
  2272.  
  2273.   If NewLen < Byte(S2[0]) Then
  2274.     NewLen := Byte(S2[0]);
  2275.  
  2276.   FillChar( S3[1], NewLen, ' ' );
  2277.   S3[0] := Char(NewLen);
  2278.   Move( S2[1], S3[1],     Byte(S2[0]) );
  2279.   Move( S1[1], S3[Index], Count );
  2280.  
  2281.   CopyOverStr := S3;
  2282.  
  2283. END;
  2284.  
  2285. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2286.  
  2287. (*-
  2288.  
  2289. [FUNCTION]
  2290.  
  2291. Function  OccurStr(                  SubS      : STRING;
  2292.                                      S         : STRING   ) : BYTE;
  2293.  
  2294. [PARAMETERS]
  2295.  
  2296. SubS        Sub-String to look for
  2297. S           Source String to Search in
  2298.  
  2299. [RETURNS]
  2300.  
  2301. The number of times the sub-string "subs" was found in the
  2302. source string "s".
  2303.  
  2304. [DESCRIPTION]
  2305.  
  2306. This function searches the source string "s" for any and all occurances
  2307. of the sub-string "subs".  It returns a counts of the number of times
  2308. "subs" occured in "S".
  2309.  
  2310. [SEE-ALSO]
  2311.  
  2312. Pos
  2313.  
  2314. [EXAMPLE]
  2315.  
  2316. VAR
  2317.   S     : STRING;
  2318.   Count : BYTE;
  2319.  
  2320. BEGIN
  2321.  
  2322.   S     := 'This is the way it is here.';
  2323.   Count := OccurStr( 'is', S );
  2324.  
  2325.   { Count = 2 }
  2326.  
  2327. END;
  2328.  
  2329. -*)
  2330.  
  2331.  
  2332. Function  OccurStr(                  SubS      : STRING;
  2333.                                      S         : STRING   ) : BYTE;
  2334.  
  2335. Var
  2336.  
  2337.   Result : BYTE;
  2338.   Pos1   : BYTE;
  2339.  
  2340. BEGIN
  2341.  
  2342.   Result := 0;
  2343.  
  2344.   {-----------------------------------------}
  2345.   { To simulate the TP60 "bug".  Otherwise, }
  2346.   { assume compiling under TP70.            }
  2347.   {-----------------------------------------}
  2348.  
  2349.   If SubS = '' Then
  2350.   {$IFDEF VER60}
  2351.     OccurStr := 1
  2352.   {$ELSE}
  2353.     OccurStr := 0
  2354.   {$ENDIF}
  2355.   Else
  2356.   BEGIN
  2357.  
  2358.     Pos1 := 1;
  2359.  
  2360.     While (S <> '') AND (Pos1 <> 0) Do
  2361.     BEGIN
  2362.  
  2363.       Pos1 := Pos( SubS, S );
  2364.  
  2365.       If Pos1 <> 0 Then
  2366.       BEGIN
  2367.  
  2368.         Inc(Result);
  2369.         Delete( S, 1, LesserInt( Pos1 + Pred(Byte(SubS[0])), Byte(S[0]) ) );
  2370.  
  2371.       END;
  2372.  
  2373.     END;
  2374.  
  2375.     OccurStr := Result;
  2376.  
  2377.   END;
  2378.  
  2379. END;
  2380.  
  2381. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2382.  
  2383. (*-
  2384.  
  2385. [FUNCTION]
  2386.  
  2387. Function  GetWords(                 S         : STRING;
  2388.                                     NumWords  : WORD     ) : STRING;
  2389.  
  2390. [PARAMETERS]
  2391.  
  2392. S           Source string to get word from
  2393.  
  2394. [RETURNS]
  2395.  
  2396. The first "numwords" found in the string "s".
  2397.  
  2398. [DESCRIPTION]
  2399.  
  2400. This function searches the source string "s" for the first "numwords"
  2401. words and returns those words.
  2402.  
  2403. [SEE-ALSO]
  2404.  
  2405. TakeQuote
  2406.  
  2407. [EXAMPLE]
  2408.  
  2409. VAR
  2410.   S,Tmp : STRING;
  2411.  
  2412. BEGIN
  2413.  
  2414.   S := 'This is a string with 9 words in it';
  2415.  
  2416.   Tmp := GetWords( S, 2 );
  2417.  
  2418.   { tmp now equals 'This is' }
  2419.  
  2420. END;
  2421.  
  2422. -*)
  2423.  
  2424.  
  2425. Function GetWords(                   S         : STRING;
  2426.                                      NumWords  : WORD      ) : STRING;
  2427.  
  2428. Var
  2429.  
  2430.   EndOfs : BYTE;
  2431.  
  2432. BEGIN
  2433.  
  2434.   { get rid of leading spaces }
  2435.  
  2436.   S := TrimChar( S, OnLeft, ' ' );
  2437.  
  2438.   { loop through the string }
  2439.  
  2440.   EndOfs := 0;
  2441.  
  2442.   While ( EndOfs <= Length( S ) ) and
  2443.         ( NumWords >0           ) Do
  2444.   BEGIN
  2445.     Inc( EndOfs );
  2446.     If S[EndOfs] = ' ' Then
  2447.       Dec( NumWords );
  2448.   END;
  2449.  
  2450.   IF S[EndOfs]=' ' Then
  2451.     Dec( EndOfs );
  2452.  
  2453.   GetWords := Copy( S, 1, EndOfs );
  2454.  
  2455.  
  2456. END;
  2457.  
  2458. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2459.  
  2460.  
  2461. (*-
  2462.  
  2463. [FUNCTION]
  2464.  
  2465. Function  TakeWords(             Var S         : STRING   ) : STRING;
  2466.  
  2467. [PARAMETERS]
  2468.  
  2469. S           Source string to take words from
  2470.  
  2471. [RETURNS]
  2472.  
  2473. The first "numwords" found in the string "s".
  2474. (VAR S modified ["numwords" are removed])
  2475.  
  2476. [DESCRIPTION]
  2477.  
  2478. This function searches the source string "s" for the first "numwords"
  2479. words and returns those words.  It also takes the words out of the
  2480. string "s"
  2481.  
  2482. [SEE-ALSO]
  2483.  
  2484. GetWords
  2485. TakeQuote
  2486.  
  2487. [EXAMPLE]
  2488.  
  2489. VAR
  2490.   S,Tmp : STRING;
  2491.  
  2492. BEGIN
  2493.  
  2494.   S := 'This is a string with 9 words in it';
  2495.  
  2496.   REPEAT
  2497.  
  2498.     Tmp := TakeWords( S,1 );
  2499.     WriteLn( Tmp );  { Writes one word at a time }
  2500.  
  2501.   UNTIL S = '';
  2502.  
  2503.   {
  2504.   Output:
  2505.  
  2506.     This
  2507.     is
  2508.     a
  2509.     string
  2510.     with
  2511.     9
  2512.     words
  2513.     in
  2514.     it
  2515.   }
  2516.  
  2517. END;
  2518.  
  2519. -*)
  2520.  
  2521.  
  2522. Function TakeWords(              Var S         : STRING;
  2523.                                      NumWords  : WORD      ) : STRING;
  2524.  
  2525. Var
  2526.  
  2527.   EndOfs : BYTE;
  2528.  
  2529. BEGIN
  2530.  
  2531.   { get rid of leading spaces }
  2532.  
  2533.   S := TrimChar( S, OnLeft, ' ' );
  2534.  
  2535.   { loop through the string }
  2536.  
  2537.   EndOfs := 0;
  2538.  
  2539.   While ( EndOfs <= Length( S ) ) and
  2540.         ( NumWords >0           ) Do
  2541.   BEGIN
  2542.     Inc( EndOfs );
  2543.     If S[EndOfs] = ' ' Then
  2544.       Dec( NumWords );
  2545.   END;
  2546.  
  2547.   IF S[EndOfs]=' ' Then
  2548.     Dec( EndOfs );
  2549.  
  2550.   TakeWords := Copy( S, 1, EndOfs );
  2551.  
  2552.   { take em out }
  2553.  
  2554.   Delete( S, 1, EndOfs );
  2555.  
  2556. END;
  2557.  
  2558. (*
  2559. Function TakeWord(               Var S         : STRING   ) : STRING;
  2560.  
  2561. Var
  2562.  
  2563.   C1 : BYTE;
  2564.   C2 : BYTE;
  2565.   S2 : STRING;
  2566.  
  2567. BEGIN
  2568.  
  2569.   C1 := 1;
  2570.   While ((S[C1] = ' ') AND
  2571.          (C1 <= Byte(S[0]))) Do
  2572.     Inc(C1);
  2573.  
  2574.   If (C1 > 80) Then
  2575.   BEGIN
  2576.  
  2577.     TakeWord := '';
  2578.     Exit;
  2579.  
  2580.   END;
  2581.  
  2582.   C2 := C1;
  2583.   While ((S[C2] <> ' ') AND
  2584.          (S[C2] <> '"') AND
  2585.          (C2 <= Byte(S[0]))) Do
  2586.     Inc(C2);
  2587.  
  2588.   If (S[C2] = '"') AND (C2 = C1) Then
  2589.     Inc(C2);
  2590.  
  2591.   Delete( S, 1, Pred(C1) );
  2592.   S2 := CopyStr( S, 1, C2 - C1 );
  2593.   Delete( S, 1, C2 - C1 );
  2594.   TakeWord := S2;
  2595.  
  2596. END;
  2597. *)
  2598.  
  2599.  
  2600. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2601.  
  2602.  
  2603. (*-
  2604.  
  2605. [FUNCTION]
  2606.  
  2607. Function  CountWords(             S              : STRING       ) : BYTE;
  2608.  
  2609. [PARAMETERS]
  2610.  
  2611. S           Source string to count the words in
  2612.  
  2613. [RETURNS]
  2614.  
  2615. The number of words in the string "S"
  2616.  
  2617. [DESCRIPTION]
  2618.  
  2619. This function returns a count of the number of words in the
  2620. string "S".
  2621.  
  2622. [SEE-ALSO]
  2623.  
  2624. GetWords
  2625. TakeWords
  2626. PosWord
  2627.  
  2628. [EXAMPLE]
  2629.  
  2630. BEGIN
  2631.        {1    2  3 4      5    6 7     8  9  }
  2632.  
  2633.   S := 'This is a string with 9 words in it';
  2634.  
  2635.   B := CountWords( S );
  2636.  
  2637.   { b now equals 9 }
  2638.  
  2639.  
  2640. END;
  2641.  
  2642. -*)
  2643.  
  2644.  
  2645. Function  CountWords(             S              : STRING       ) : BYTE;
  2646.  
  2647. Var
  2648.  
  2649.   Ofs      : BYTE;
  2650.   NumWords : BYTE;
  2651.  
  2652. BEGIN
  2653.  
  2654.   { get rid of leading/trailing spaces and add space terminator }
  2655.  
  2656.   S := TrimChar( S, OnCENTER, ' ' )+' ';
  2657.  
  2658.   If Length(S)=1 Then
  2659.   BEGIN
  2660.     CountWords := 0;
  2661.     Exit;
  2662.   END;
  2663.  
  2664.   NumWords := 0;
  2665.  
  2666.   { loop through the string }
  2667.  
  2668.   For Ofs := 1 to Length( S ) Do
  2669.   BEGIN
  2670.  
  2671.     If (S[Ofs]       =  ' '          ) and
  2672.  
  2673.        ( ( Succ(ofs)=Length(S) ) or
  2674.          ( S[Succ(ofs)] <> ' ' )     ) Then
  2675.  
  2676.       Inc( NumWords );
  2677.  
  2678.   END;
  2679.  
  2680.   CountWords := NumWords;
  2681.  
  2682.  
  2683. END;
  2684.  
  2685. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2686.  
  2687. (*-
  2688.  
  2689. [FUNCTION]
  2690.  
  2691. Function  TakeQuote(             Var S         : STRING   ) : STRING;
  2692.  
  2693. [PARAMETERS]
  2694.  
  2695. S           VAR Source string to parse (MODIFIED ON RETURN)
  2696.  
  2697. [RETURNS]
  2698.  
  2699. The first quoted text-string found in the source string "S".
  2700.  
  2701. [DESCRIPTION]
  2702.  
  2703. This function searches for and returns the first quoted string in
  2704. the source string "S".  Additionally, if a quoted string is found,
  2705. it is removed form the string "S".  The returned/taken string
  2706. does not include the quote (") characters.
  2707.  
  2708. [SEE-ALSO]
  2709.  
  2710. TakeWord
  2711.  
  2712. [EXAMPLE]
  2713.  
  2714. VAR
  2715.   S,T : STRING;
  2716.  
  2717. BEGIN
  2718.  
  2719.   S := 'The Password is "Zulu"';
  2720.   T := TakeQuote( S );
  2721.  
  2722.   {------------------------}
  2723.   { T = 'Zulu'             }
  2724.   { S = 'The Password is ' }
  2725.   {------------------------}
  2726.  
  2727. END;
  2728.  
  2729. -*)
  2730.  
  2731.  
  2732. Function TakeQuote(              Var S         : STRING   ) : STRING;
  2733.  
  2734. Var
  2735.  
  2736.   Cmd    : STRING;
  2737.   MsgCmd : STRING;
  2738.   Idx1   : BYTE;
  2739.   Idx2   : BYTE;
  2740.   Count  : BYTE;
  2741.  
  2742. BEGIN
  2743.  
  2744.   Idx1 := Pos( '"', S );
  2745.   Delete( S, Idx1, 1 );
  2746.   Idx2 := Pos( '"', S );
  2747.   Count := Idx2 - Idx1;
  2748.  
  2749.   TakeQuote := Copy( S, Idx1, Count );
  2750.   Delete( S, Pred(Idx1), Count+2 );
  2751.  
  2752. END;
  2753.  
  2754. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2755.  
  2756. (*-
  2757.  
  2758. [FUNCTION]
  2759.  
  2760. Function GetQuote(                 S         : STRING   ) : STRING;
  2761.  
  2762. [PARAMETERS]
  2763.  
  2764. S           the string to look for a quote in.
  2765.  
  2766. [RETURNS]
  2767.  
  2768. The first quoted text-string found in the source string "S".
  2769.  
  2770. [DESCRIPTION]
  2771.  
  2772. This function searches for and returns the first quoted string in
  2773. the source string "S".  The returned string does not include the
  2774. quote (") characters.
  2775.  
  2776. [SEE-ALSO]
  2777.  
  2778. TakeWord
  2779. TakeQuote
  2780.  
  2781. [EXAMPLE]
  2782.  
  2783. VAR
  2784.   S,T : STRING;
  2785.  
  2786. BEGIN
  2787.  
  2788.   S := 'The Password is "Zulu"';
  2789.   T := TakeQuote( S );
  2790.  
  2791.   {------------------------------}
  2792.   { T = 'Zulu'                   }
  2793.   { S = 'The Password is "Zulu"' }
  2794.   {------------------------------}
  2795.  
  2796. END;
  2797.  
  2798. -*)
  2799.  
  2800.  
  2801. Function GetQuote(                  S         : STRING   ) : STRING;
  2802.  
  2803. Var
  2804.  
  2805.   P1, P2 : INTEGER;
  2806.  
  2807. BEGIN
  2808.  
  2809.   P1 := Pos( '"', S );
  2810.  
  2811.   If P1>0 Then
  2812.   BEGIN
  2813.  
  2814.     P2 := PosAfter( '"', S, P1+1 )-1;
  2815.  
  2816.     If P2>0 Then
  2817.       GetQuote := Copy( S, P1+1, P2-P1 )
  2818.     Else
  2819.       GetQuote := '';
  2820.  
  2821.   END
  2822.   ELSE
  2823.     GetQuote := '';
  2824.  
  2825.  
  2826. END;
  2827.  
  2828.  
  2829. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2830.  
  2831.  
  2832.  
  2833.  
  2834. (*-
  2835.  
  2836. [FUNCTION]
  2837.  
  2838. Function  AddCommas(                 S         : STRING   ) : STRING;
  2839.  
  2840. [PARAMETERS]
  2841.  
  2842. S           Text-String representation of a Number
  2843.  
  2844. [RETURNS]
  2845.  
  2846. string representation of the number with proper commas inserted.
  2847.  
  2848. [DESCRIPTION]
  2849.  
  2850. This function takes a Number in Text format (IE: "10", not "ten") and
  2851. inserts the commas at the hundered, thousands, ten-thousands place,
  2852. etc. until the number has been full "commatized".
  2853.  
  2854. [SEE-ALSO]
  2855.  
  2856. (None)
  2857.  
  2858. [EXAMPLE]
  2859.  
  2860. VAR
  2861.   S : STRING;
  2862.  
  2863. BEGIN
  2864.  
  2865.   S := '123456789';
  2866.   S := AddCommas( S );
  2867.  
  2868.   { S = '123,456,789' }
  2869.  
  2870. END;
  2871.  
  2872. -*)
  2873.  
  2874.  
  2875. Function AddCommas(                  S         : STRING   ) : STRING;
  2876.  
  2877. Var
  2878.  
  2879.   Index     : WORD;
  2880.   NextIndex : WORD;
  2881.   Count     : WORD;
  2882.   L1        : BYTE;
  2883.   L2        : BYTE;
  2884.  
  2885. BEGIN
  2886.  
  2887.   NextIndex := 1;
  2888.   Index := NextIndex;
  2889.  
  2890.   REPEAT
  2891.  
  2892.     While ( Index <= Byte(S[0]) ) AND
  2893.           ( NOT IsNum(S[Index]) ) Do
  2894.       Inc( Index );
  2895.  
  2896.     If Index <= Byte(S[0]) Then
  2897.     BEGIN
  2898.  
  2899.       Count := Index;
  2900.       While ( Count < Byte(S[0]) ) AND
  2901.             ( IsNum(S[Succ(Count)]) ) Do
  2902.         Inc( Count );
  2903.  
  2904.       NextIndex := Succ(Count);
  2905.  
  2906.       If (S[NextIndex] = '.') Then
  2907.       BEGIN
  2908.  
  2909.         Inc(NextIndex);
  2910.  
  2911.         While ( NextIndex <= Byte(S[0]) ) AND
  2912.               ( IsNum(S[NextIndex]) )  Do
  2913.           Inc( NextIndex );
  2914.  
  2915.       END;
  2916.  
  2917.       L2 := 0;
  2918.       For L1 := LesserInt(Count, Byte(S[0])) DownTo Index Do
  2919.       BEGIN
  2920.  
  2921.         Inc(L2);
  2922.  
  2923.         If (L2 = 3) AND
  2924.            (L1 <> Index) Then
  2925.         BEGIN
  2926.  
  2927.           Insert(',', S, L1);
  2928.           Inc(NextIndex);
  2929.           L2 := 0;
  2930.  
  2931.         END;
  2932.  
  2933.       END;
  2934.  
  2935.       Index := NextIndex;
  2936.  
  2937.     END;
  2938.  
  2939.   UNTIL (Index > Byte(S[0]));
  2940.  
  2941.   AddCommas := S;
  2942.  
  2943. END;
  2944.  
  2945. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  2946.  
  2947.  
  2948. (*-
  2949.  
  2950. [FUNCTION]
  2951.  
  2952. Procedure CRC16String(               S         : STRING;
  2953.                                  Var Result    : WORD;
  2954.                                      NewResult : BOOLEAN  );
  2955.  
  2956. [PARAMETERS]
  2957.  
  2958. S           String to CRC
  2959. Result      VAR Returned 16-bit CRC of String plus prior CRC
  2960. NewResult   flag to indicate if this is an intial CRC operation
  2961.  
  2962. [RETURNS]
  2963.  
  2964. (VAR     : [Result] 16-bit CRC of string plus initial CRC value)
  2965.  
  2966. [DESCRIPTION]
  2967.  
  2968. Computes a 16-Bit CRC on the specified string "S".
  2969.  
  2970. If the NewResult flag is TRUE then "result" is based soley upon the
  2971. provided string.  If the "NewResult" Flag is FALSE then the result is
  2972. computed as a continuation of a CRC which has been previously
  2973. calculated and is passed in the variable "result"
  2974.  
  2975. [SEE-ALSO]
  2976.  
  2977. CRC16Char
  2978. CRC16Buffer
  2979. CRC32Char
  2980. CRC32String
  2981. CRC32Buffer
  2982.  
  2983. [EXAMPLE]
  2984.  
  2985. VAR
  2986.   S      : STRING;
  2987.   CRC32  : LONGINT;
  2988.   NewCRC : BOOLEAN;
  2989. BEGIN
  2990.  
  2991. VAR
  2992.   S     : STRING;
  2993.   CRC16 : WORD;
  2994.  
  2995. BEGIN
  2996.  
  2997.   S := 'She sells sea shells down by the sea shore';
  2998.   CRC16String( S, CRC32, TRUE );
  2999.  
  3000.   { CRC16 = $4941 }
  3001.  
  3002. END;
  3003.  
  3004. -*)
  3005.  
  3006. Procedure CRC16String(               S         : STRING;
  3007.                                  Var Result    : WORD;
  3008.                                      NewResult : BOOLEAN  );
  3009.  
  3010. Var
  3011.  
  3012.   P : POINTER;
  3013.   I : WORD;
  3014.  
  3015. BEGIN
  3016.  
  3017.   If NewResult Then
  3018.     Result := $FFFF;
  3019.  
  3020.   For I := 1 to Byte(S[0]) Do
  3021.     CRC16Char( S[I], Result );
  3022.  
  3023. END;
  3024.  
  3025. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3026.  
  3027. (*-
  3028. [FUNCTION]
  3029.  
  3030. Procedure CRC32String(               S         : STRING;
  3031.                                  Var Result    : LONGINT;
  3032.                                      NewResult : BOOLEAN  );
  3033.  
  3034.  
  3035. [PARAMETERS]
  3036.  
  3037. S           String to CRC
  3038. Result      VAR Returned 32-bit CRC of String plus prior CRC
  3039. NewResult   flag to indicate if this is an intial CRC operation
  3040.  
  3041. [RETURNS]
  3042.  
  3043. (VAR     : [Result] 32-bit CRC of string plus initial CRC value)
  3044.  
  3045. [DESCRIPTION]
  3046.  
  3047. Computes a 32-Bit CRC on the specified string "S".
  3048.  
  3049. If the NewResult flag is TRUE then "result" is based soley upon the
  3050. provided string.  If the "NewResult" Flag is FALSE then the result is
  3051. computed as a continuation of a CRC which has been previously
  3052. calculated and is passed in the variable "result"
  3053.  
  3054. [SEE-ALSO]
  3055.  
  3056. CRC16Char
  3057. CRC16String
  3058. CRC16Buffer
  3059. CRC32Char
  3060. CRC32Buffer
  3061.  
  3062. [EXAMPLE]
  3063.  
  3064. VAR
  3065.   S     : STRING;
  3066.   CRC32 : LONGINT;
  3067.  
  3068. BEGIN
  3069.  
  3070.   S := 'She sells sea shells down by the sea shore';
  3071.   CRC32String( S, CRC32, TRUE );
  3072.  
  3073.   { CRC32 = $7C6912A6 }
  3074.  
  3075. END;
  3076.  
  3077. -*)
  3078.  
  3079. Procedure CRC32String(               S         : STRING;
  3080.                                  Var Result    : LONGINT;
  3081.                                      NewResult : BOOLEAN  );
  3082.  
  3083. Var
  3084.  
  3085.   P : POINTER;
  3086.   I : WORD;
  3087.  
  3088. BEGIN
  3089.  
  3090.   If NewResult Then
  3091.     Result := $FFFFFFFF;
  3092.  
  3093.   For I := 1 to Byte(S[0]) Do
  3094.     CRC32Char( S[I], Result );
  3095.  
  3096. END;
  3097.  
  3098. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3099.  
  3100. (*-
  3101.  
  3102. [FUNCTION]
  3103.  
  3104. Function  WordWrap(           Var Stt            : STRING;
  3105.                                   MaxWidth       : BYTE         ) : STRING;
  3106.  
  3107. [PARAMETERS]
  3108.  
  3109. Stt         Source string.
  3110. MaxWidth    Right most edge at which to cut off source string.
  3111.  
  3112. [RETURNS]
  3113.  
  3114. Stt         Unused portion of result.
  3115. String truncated to last Grammar or Space character.
  3116.  
  3117.  
  3118. [DESCRIPTION]
  3119.  
  3120. Truncates the source string to fit smoothly within a certain "maxwidth".
  3121. Returns the string truncated to the last grammar or space character.
  3122.  
  3123. The left-over portion of the string is returned in "Stt".  If no grammer
  3124. delimiter is found, then the original source string is returned.
  3125.  
  3126. [SEE-ALSO]
  3127.  
  3128. TakeQuote
  3129.  
  3130. [EXAMPLE]
  3131.  
  3132.  
  3133.   {              2         3         4         5
  3134.         123456789012345678901234567890123456789012345678901   }
  3135.  
  3136.   S := 'Now this is the time for all gentlemen to word wrap.';
  3137.  
  3138.   T := WordWrap( S, 45 );
  3139.  
  3140.   { s now equals "Now this is the time for all" }
  3141.   { t now equals "gentlemen to word wrap."      }
  3142.  
  3143.  
  3144. -*)
  3145.  
  3146. Function  WordWrap(           Var Stt            : STRING;
  3147.                                   MaxWidth       : BYTE         ) : STRING;
  3148.  
  3149. Var
  3150.  
  3151.   Temp  : STRING;
  3152.   Count : WORD;
  3153.   Size  : BYTE;
  3154.  
  3155. BEGIN
  3156.  
  3157.   Temp := Stt;
  3158.   Stt  := '';
  3159.  
  3160.   If Length(Temp) < MaxWidth Then
  3161.      MaxWidth := Length(Temp);
  3162.  
  3163.   If Length(temp) > MaxWidth Then
  3164.   For Count := MaxWidth Downto 1 Do
  3165.   Begin
  3166.  
  3167.     If (Temp[Count] = #32) or IsGrammar(Temp[Count]) Then
  3168.     BEGIN
  3169.  
  3170.       Stt := Copy ( Temp, 1,Count );
  3171.  
  3172.       Delete(Temp,1,count);
  3173. {      Move( Temp[Succ(Count)], Stt[1], Size);}
  3174. {      Stt[0] := Char(Size);}
  3175.  
  3176. {      Temp[0] := Char(Count);}
  3177.  
  3178.       Count := 1;
  3179.  
  3180.     END;
  3181.   End
  3182.   Else
  3183.   Begin
  3184.      Stt  := Temp;
  3185.      Temp := '';
  3186.   End;
  3187.  
  3188.  
  3189.    WordWrap := stt;
  3190.    Stt      := Temp;
  3191.  
  3192. END;
  3193.  
  3194. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3195.  
  3196. Function  TruncAfter(             S              : STRING;
  3197.                                   After          : STRING       ) : STRING;
  3198.  
  3199. Var
  3200.  
  3201.   P : INTEGER;
  3202.  
  3203. BEGIN
  3204.  
  3205.  
  3206.   P := Pos( After, S );
  3207.  
  3208.   If P>0 Then
  3209.   BEGIN
  3210.  
  3211.     TruncAfter := Copy( S, 1, P+Length(After )-1 );
  3212.  
  3213.   END
  3214.   ELSE
  3215.     TruncAfter := S;
  3216.  
  3217. END;
  3218.  
  3219. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3220.  
  3221. Function  TruncAfterEnd(          S              : STRING;
  3222.                                   After          : STRING       ) : STRING;
  3223.  
  3224. Var
  3225.  
  3226.   P : INTEGER;
  3227.  
  3228. BEGIN
  3229.  
  3230.  
  3231.   P := PosEnd( After, S );
  3232.  
  3233.   If P>0 Then
  3234.   BEGIN
  3235.  
  3236.     TruncAfterEnd := Copy( S, 1, P+Length(After )-1 );
  3237.  
  3238.   END
  3239.   ELSE
  3240.     TruncAfterEnd := S;
  3241.  
  3242. END;
  3243.  
  3244. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3245.  
  3246. Function  TruncAt(                S              : STRING;
  3247.                                   At             : STRING       ) : STRING;
  3248.  
  3249. Var
  3250.  
  3251.   P : INTEGER;
  3252.  
  3253. BEGIN
  3254.  
  3255.  
  3256.   P := Pos( At, S );
  3257.  
  3258.   If P>0 Then
  3259.   BEGIN
  3260.  
  3261.     TruncAt := Copy( S, 1, P-1 );
  3262.  
  3263.   END
  3264.   ELSE
  3265.     TruncAt := S;
  3266.  
  3267. END;
  3268.  
  3269. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3270.  
  3271. Function  TruncAtEnd(             S              : STRING;
  3272.                                   At             : STRING       ) : STRING;
  3273.  
  3274. Var
  3275.  
  3276.   P : INTEGER;
  3277.  
  3278. BEGIN
  3279.  
  3280.  
  3281.   P := PosEnd( At, S );
  3282.  
  3283.   If P>0 Then
  3284.   BEGIN
  3285.  
  3286.     TruncAtEnd := Copy( S, 1, P-1 );
  3287.  
  3288.   END
  3289.   ELSE
  3290.     TruncAtEnd := S;
  3291.  
  3292. END;
  3293.  
  3294. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3295.  
  3296. (*-
  3297.  
  3298. [FUNCTION]
  3299.  
  3300. Function  PosBuf(                 SubS           : STRING;
  3301.                               Var Buf;
  3302.                                   Count          : WORD         ) : LONGINT;
  3303.  
  3304. [PARAMETERS]
  3305.  
  3306. Buf         Buffer to look at.
  3307. Count       Number of bytes to look through.
  3308. SubS        Substring to look for.
  3309.  
  3310. [RETURNS]
  3311.  
  3312. Location of SubS within the given buffer.
  3313.  
  3314. [DESCRIPTION]
  3315.  
  3316. Finds location of a substring within a buffer.  Will return -1 if not
  3317. found.
  3318.  
  3319. [SEE-ALSO]
  3320.  
  3321. StrInBufNoCase
  3322.  
  3323. [EXAMPLE]
  3324.  
  3325. Const BufMax : WORD = 1000;
  3326. Type TBuf = Array[0..0] of Char;
  3327. Var
  3328.   Buf     : ^TBuf;
  3329.   SubS    : STRING;
  3330.   PlaceAt : LONGINT;
  3331.  
  3332.   FS      : TFontSet;
  3333.  
  3334. BEGIN
  3335.   Getmem( Buf, BufMax );
  3336.   FillChar( Buf^, BufMax, 0 );
  3337.   SubS := 'Look for me';
  3338.   PlaceAt := 42;
  3339.   Move(SubS[1], Buf^[PlaceAt], Byte(SubS[0]));
  3340.   LookS := 'Look For Me';
  3341.   WriteLn( 'Found at ', PosBufNoCase(SubS, Buf^, BufMax) ); { Found at 42 }
  3342.   Freemem( Buf, BufMax );
  3343. END.
  3344.  
  3345. -*)
  3346.  
  3347. Function  PosBuf(                 SubS           : STRING;
  3348.                               Var Buf;
  3349.                                   Count          : WORD         ) : LONGINT;
  3350.  
  3351. Var
  3352.  
  3353.   PosB   : LONGINT;
  3354.   PosS   : BYTE;
  3355.   P      : POINTER;
  3356.  
  3357. BEGIN
  3358.  
  3359.   PosB := 0;
  3360.   PosS := 1;
  3361.  
  3362.   While ( PosB <= Count ) AND
  3363.         ( PosS <= Byte(SubS[0]) ) Do
  3364.   BEGIN
  3365.  
  3366.     If (TCharArray(Buf)[PosB] = SubS[PosS]) Then
  3367.       Inc(PosS)
  3368.     Else
  3369.       PosS := 1;
  3370.  
  3371.     Inc(PosB);
  3372.  
  3373.   END;
  3374.  
  3375.   If PosS > Byte(SubS[0]) Then
  3376.     PosBuf := Pred(PosB) - Byte(SubS[0])
  3377.   Else
  3378.     PosBuf := -1;
  3379.  
  3380. END;
  3381.  
  3382. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3383.  
  3384. (*-
  3385.  
  3386. [FUNCTION]
  3387.  
  3388. Function  PosBufNoCase(           SubS           : STRING;
  3389.                               Var Buf;
  3390.                                   Count          : WORD         ) : LONGINT;
  3391.  
  3392. [PARAMETERS]
  3393.  
  3394. Buf         Buffer to look at.
  3395. Count       Number of bytes to look through.
  3396. SubS        Substring to look for.
  3397.  
  3398. [RETURNS]
  3399.  
  3400. Location of SubS within the given buffer.
  3401.  
  3402. [DESCRIPTION]
  3403.  
  3404. Works same as StrInBuf, except this ignores case.
  3405.  
  3406. [SEE-ALSO]
  3407.  
  3408. StrInBuf
  3409.  
  3410. [EXAMPLE]
  3411.  
  3412. Const BufMax : WORD = 1000;
  3413. Type TBuf = Array[0..0] of Char;
  3414. Var
  3415.   Buf     : ^TBuf;
  3416.   SubS    : STRING;
  3417.   LookS   : STRING;
  3418.   PlaceAt : LONGINT;
  3419.  
  3420.   FS      : TFontSet;
  3421.  
  3422. BEGIN
  3423.   Getmem( Buf, BufMax );
  3424.   FillChar( Buf^, BufMax, 0 );
  3425.   SubS := 'Look for me';
  3426.   PlaceAt := 990;
  3427.   Move(SubS[1], Buf^[PlaceAt], Byte(SubS[0]));
  3428.   LookS := 'Look For Me';
  3429.   WriteLn( 'Found at ', PosBufNoCase(LookS, Buf^, BufMax) ); { Found at 990 }
  3430.   Freemem( Buf, BufMax );
  3431. END.
  3432.  
  3433. -*)
  3434.  
  3435. Function  PosBufNoCase(           SubS           : STRING;
  3436.                               Var Buf;
  3437.                                   Count          : WORD         ) : LONGINT;
  3438.  
  3439. Var
  3440.  
  3441.   PosB   : LONGINT;
  3442.   PosS   : BYTE;
  3443.   P      : POINTER;
  3444.  
  3445. BEGIN
  3446.  
  3447.   PosB := 0;
  3448.   PosS := 1;
  3449.  
  3450.   While ( PosB <= Count ) AND
  3451.         ( PosS <= Byte(SubS[0]) ) Do
  3452.   BEGIN
  3453.  
  3454.     If ( UpCase(TCharArray(Buf)[PosB]) = UpCase(SubS[PosS]) ) Then
  3455.       Inc(PosS)
  3456.     Else
  3457.       PosS := 1;
  3458.  
  3459.     Inc(PosB);
  3460.  
  3461.   END;
  3462.  
  3463.   If PosS > Byte(SubS[0]) Then
  3464.     PosBufNoCase := Pred(PosB) - Byte(SubS[0])
  3465.   Else
  3466.     PosBufNoCase := -1;
  3467.  
  3468. END;
  3469.  
  3470. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3471.  
  3472. (*-
  3473.  
  3474. [FUNCTION]
  3475.  
  3476. Procedure StrToArray(                S         : STRING;
  3477.                                  Var TheArray            );
  3478.  
  3479. [PARAMETERS]
  3480.  
  3481. S           Pascal String to convert to an array
  3482. TheArray    VAR working array to return results in
  3483.  
  3484. [RETURNS]
  3485.  
  3486. Function : None
  3487. (Var     : [TheArray] The array of characters so stored)
  3488.  
  3489. [DESCRIPTION]
  3490.  
  3491. This function converts a PASCAL String into an Array of Characters.
  3492. (NOTE: The Array is NOT Zero Terminated or length denoted by any means!)
  3493.  
  3494. [SEE-ALSO]
  3495.  
  3496. ArrayToStr
  3497.  
  3498. [EXAMPLE]
  3499.  
  3500. TYPE
  3501.   TArr = ARRAY[1..10] of CHAR;
  3502.  
  3503. VAR
  3504.   S   : STRING;
  3505.   Arr : TArr;
  3506.  
  3507. BEGIN
  3508.  
  3509.   S := 'Hello';
  3510.   StrToArray( S, Arr );
  3511.  
  3512.   { Arr[1]='H', .. ,Arr[5]='o' }
  3513.   { Data Now in Array Format   }
  3514.  
  3515. END;
  3516.  
  3517. -*)
  3518.  
  3519.  
  3520. Procedure StrToArray(                S         : STRING;
  3521.                                  Var TheArray            );
  3522.  
  3523. Var
  3524.  
  3525.   P : POINTER;
  3526.  
  3527. BEGIN
  3528.  
  3529.   P := Ptr( Seg( S ), Succ(Ofs( S )) );
  3530.   Move( P^, TheArray, Byte(S[0]) );
  3531.  
  3532. END;   { Of StrToArray }
  3533.  
  3534. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3535.  
  3536. (*-
  3537.  
  3538. [FUNCTION]
  3539.  
  3540. Function  ArrayToStr(            Var TheArray;
  3541.                                      Len       : BYTE    ) : STRING;
  3542.  
  3543. [PARAMETERS]
  3544.  
  3545. TheArray    VAR Address of the source array to convert to a string
  3546. Len         Desired final string length
  3547.  
  3548. [RETURNS]
  3549.  
  3550. Pascal String created from array
  3551.  
  3552. [DESCRIPTION]
  3553.  
  3554. This function converts an Array of Characters into a PASCAL String.
  3555. (NOTE: The input Array need not be terminated in any way, but will
  3556. be exactly duplicated up to the length "Len" - even if beyond the
  3557. Array!)
  3558.  
  3559. [SEE-ALSO]
  3560.  
  3561. StrToArray
  3562.  
  3563. [EXAMPLE]
  3564.  
  3565. TYPE
  3566.   TArr = ARRAY[1..10] of CHAR;
  3567.  
  3568. VAR
  3569.   S   : STRING;
  3570.   Arr : TArr;
  3571.  
  3572. BEGIN
  3573.  
  3574.   Arr[1] := 'Y';
  3575.   Arr[2] := 'e';
  3576.   Arr[3] := 's';
  3577.  
  3578.   S := ArrayToStr( Arr, 3 );
  3579.  
  3580.   { S = 'Yes' }
  3581.  
  3582. END;
  3583.  
  3584. -*)
  3585.  
  3586.  
  3587. Function  ArrayToStr(            Var TheArray;
  3588.                                      Len       : BYTE    ) : STRING;
  3589.  
  3590. Var
  3591.  
  3592.   P : POINTER;
  3593.   S : STRING;
  3594.  
  3595. BEGIN
  3596.  
  3597.   P          := Ptr( Seg( TheArray ),Ofs( TheArray ) );
  3598.   Move( P^, S[1], Len );
  3599.   S[0]       := Char( Len );
  3600.   ArrayToStr := S;
  3601.  
  3602. END;   { Of ArrayToStr }
  3603.  
  3604. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3605.  
  3606. (*-
  3607.  
  3608. [FUNCTION]
  3609.  
  3610. Procedure StrToAsciiZ(               S         : STRING;
  3611.                                  Var AsciiZStr           );
  3612.  
  3613. [PARAMETERS]
  3614.  
  3615. S           Pascal String to convert into an AsciiZ String
  3616. AsciiZStr   VAR working array ton return AsciiZ string in
  3617.  
  3618. [RETURNS]
  3619.  
  3620. Function : None
  3621. (Var     : [AsciiZStr] The new ASCIIZ String)
  3622.  
  3623. [DESCRIPTION]
  3624.  
  3625. This Procedure converts a PASCAL String into an ASCIIZ String (a null-
  3626. terminated character array).  This is particularly useful when
  3627. converting Pascal Strings to C Strings.
  3628.  
  3629. [SEE-ALSO]
  3630.  
  3631. AsciiZtoStr
  3632.  
  3633. [EXAMPLE]
  3634.  
  3635. TYPE
  3636.   TArr = ARRAY[1..10] of CHAR;
  3637.  
  3638. VAR
  3639.   S   : STRING;
  3640.   Arr : TArr;
  3641.  
  3642. BEGIN
  3643.  
  3644.   S := 'Yes';
  3645.   StrToAsciiZ( S, Arr );
  3646.  
  3647.   { Arr[1]='Y' }
  3648.   { Arr[2]='e' }
  3649.   { Arr[3]='s' }
  3650.   { Arr[4]=#0  - NULL Terminated! }
  3651.  
  3652. END;
  3653.  
  3654. -*)
  3655.  
  3656.  
  3657. Procedure StrToAsciiZ(               S         : STRING;
  3658.                                  Var AsciiZStr           );
  3659.  
  3660. BEGIN
  3661.  
  3662.   {------------------------------------------------------------}
  3663.   { Convert a string to a array of chars with terminating null }
  3664.   {------------------------------------------------------------}
  3665.  
  3666.   Move( S[1], AsciiZStr, Byte( S[0] ) );
  3667.   TCharArray( AsciiZStr )[ Byte( S[0] ) + 1 ] := #0;
  3668.  
  3669. END;
  3670.  
  3671. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3672.  
  3673. (*-
  3674.  
  3675. [FUNCTION]
  3676.  
  3677. Function  AsciiZtoStr(           Var AsciiZStr           ) : STRING;
  3678.  
  3679. [PARAMETERS]
  3680.  
  3681. AsciiZStr   VAR address of source AsciiZ string to convert to a string
  3682.  
  3683. [RETURNS]
  3684.  
  3685. Pascal String created from AsciiZ source string
  3686.  
  3687. [DESCRIPTION]
  3688.  
  3689. This function converts an ASCIIZ String (a null-terminated character
  3690. array) into a PASCAL String.  This is particularly useful when
  3691. converting a C String to a Pascal String.
  3692.  
  3693. [SEE-ALSO]
  3694.  
  3695. StrToAsciiZ
  3696.  
  3697. [EXAMPLE]
  3698.  
  3699. TYPE
  3700.   TArr = ARRAY[1..10] of CHAR;
  3701.  
  3702. VAR
  3703.   S   : STRING;
  3704.   Arr : TArr;
  3705.  
  3706. BEGIN
  3707.  
  3708.   Arr[1] := 'Y';
  3709.   Arr[2] := 'e';
  3710.   Arr[3] := 's';
  3711.   Arr[4] := #0;
  3712.  
  3713.   S := AsciiZtoStr( Arr );
  3714.  
  3715.   { S = 'Yes' }
  3716.  
  3717. END;
  3718.  
  3719. -*)
  3720.  
  3721.  
  3722. Function  AsciiZtoStr(           Var AsciiZStr        ) : STRING;
  3723.  
  3724.  
  3725. Var
  3726.  
  3727.   S : STRING;
  3728.   Z : INTEGER;
  3729.  
  3730.  
  3731. BEGIN
  3732.  
  3733. (*
  3734.   ASM
  3735.  
  3736.     LDS SI  AsciiZStr
  3737.     MOV DI, SI
  3738.  
  3739.     CLD
  3740.     MOV  AL, 0
  3741.  
  3742.     REPZ SCASB
  3743.  
  3744.     SUB DI, SI
  3745.  
  3746.     MOV Z, DI
  3747.  
  3748.  
  3749.   END;
  3750. *)
  3751.  
  3752.   Z := 0;
  3753.   While ( TCharArrayZ(AsciiZStr)[Z] <> #0 ) Do
  3754.     Inc( Z );
  3755.  
  3756.   Move( AsciiZStr, S[1], Z );
  3757.   Byte( S[0] ) := Z;
  3758.  
  3759.   AsciiZtoStr  := S;
  3760.  
  3761. END;
  3762.  
  3763.  
  3764.  
  3765. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3766.  
  3767.  
  3768.  
  3769.  
  3770. (*-
  3771.  
  3772. [FUNCTION]
  3773.  
  3774. Function  GetStrNumType(             S         : STRING  ) : BYTE;
  3775.  
  3776. [PARAMETERS]
  3777.  
  3778. S           "Valued" string needing a type
  3779.  
  3780. [RETURNS]
  3781.  
  3782. Byte value of typed string.
  3783.  
  3784. [DESCRIPTION]
  3785.  
  3786. Figures what system is needed to express the valued string.  Some common
  3787. systems are:
  3788.  
  3789.   String      Type     Value
  3790.   ----------- -------- -----
  3791.     ####      decimal    1
  3792.     ####d     decimal    1
  3793.    $####      hex        2
  3794.     ####h     hex        2
  3795.   0x####      hex        2
  3796.     ####b     binary     3
  3797.  
  3798. [SEE-ALSO]
  3799.  
  3800. [EXAMPLE]
  3801.  
  3802.   A := GetStrNumType( '$1234' );
  3803.  
  3804.   { A now equals 2 }
  3805.  
  3806. -*)
  3807.  
  3808. Function  GetStrNumType(             S         : STRING  ) : BYTE;
  3809.  
  3810. BEGIN
  3811.  
  3812.   S := UpperString( TrimChar( S, ONCENTER, ' ' ) );
  3813.  
  3814.   If (   S[1] = '$' ) OR
  3815.      ( ( S[1] = '0' ) AND ( UpCase(S[2]) = 'X' ) ) OR
  3816.      (   UpCase(S[Byte(S[0])]) = 'H' ) Then
  3817.     GetStrNumType := 2
  3818.   Else
  3819.   If ( UpCase(S[Byte(S[0])]) = 'B' ) Then
  3820.     GetStrNumType := 3
  3821.   Else
  3822.     GetStrNumType := 1;
  3823.  
  3824. END;
  3825.  
  3826. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3827.  
  3828. Function  StrToByteEx(               S         : STRING  ) : BYTE;
  3829.  
  3830. BEGIN
  3831.  
  3832.   Case GetStrNumType( S ) of
  3833.  
  3834.     1: StrToByteEx := StrToInt( S );
  3835.     2: StrToByteEx := HexToByte( S );
  3836.     3: StrToByteEx := BinToByte( S );
  3837.  
  3838.   END;
  3839.  
  3840. END;
  3841.  
  3842. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3843.  
  3844. (*-
  3845.  
  3846. [FUNCTION]
  3847.  
  3848. [PARAMETERS]
  3849.  
  3850. [RETURNS]
  3851.  
  3852. [DESCRIPTION]
  3853.  
  3854. [SEE-ALSO]
  3855.  
  3856. [EXAMPLE]
  3857.  
  3858. -*)
  3859.  
  3860. Function  StrToWordEx(               S         : STRING  ) : WORD;
  3861.  
  3862. BEGIN
  3863.  
  3864.   Case GetStrNumType( S ) of
  3865.  
  3866.     1: StrToWordEx := StrToInt( S );
  3867.     2: StrToWordEx := HexToWord( S );
  3868.     3: StrToWordEx := BinToWord( S );
  3869.  
  3870.   END;
  3871.  
  3872. END;
  3873.  
  3874. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3875.  
  3876. (*-
  3877.  
  3878. [FUNCTION]
  3879.  
  3880. Function  StrToIntEx(                S         : STRING  ) : INTEGER;
  3881.  
  3882. [PARAMETERS]
  3883.  
  3884. S           Source String representing Integer Value
  3885.  
  3886. [RETURNS]
  3887.  
  3888. Integer Value
  3889.  
  3890. [DESCRIPTION]
  3891.  
  3892. ****** THIS FUNCTION NOT IMPLEMENTED! ******
  3893.  
  3894. [SEE-ALSO]
  3895.  
  3896. [EXAMPLE]
  3897.  
  3898. -*)
  3899.  
  3900. Function  StrToIntEx(                S         : STRING  ) : INTEGER;
  3901.  
  3902. BEGIN
  3903.  
  3904.   Case GetStrNumType( S ) of
  3905.  
  3906.     1: StrToIntEx := StrToInt( S );
  3907.     2: StrToIntEx := HexToInt( S );
  3908.     3: StrToIntEx := BinToInt( S );
  3909.  
  3910.   END;
  3911.  
  3912. END;
  3913.  
  3914.  
  3915. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3916.  
  3917. (*-
  3918.  
  3919. [FUNCTION]
  3920.  
  3921. [PARAMETERS]
  3922.  
  3923. [RETURNS]
  3924.  
  3925. [DESCRIPTION]
  3926.  
  3927. [SEE-ALSO]
  3928.  
  3929. [EXAMPLE]
  3930.  
  3931. -*)
  3932.  
  3933. Function  StrToLongEx(               S         : STRING  ) : LONGINT;
  3934.  
  3935. BEGIN
  3936.  
  3937.   Case GetStrNumType( S ) of
  3938.  
  3939.     1: StrToLongEx := StrToInt( S );
  3940.     2: StrToLongEx := HexToLong( S );
  3941.     3: StrToLongEx := BinToLong( S );
  3942.  
  3943.   END;
  3944.  
  3945. END;
  3946.  
  3947.  
  3948. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  3949.  
  3950. (*-
  3951.  
  3952. [FUNCTION]
  3953.  
  3954. Function  VStrNew(                S             : STRING        ) : POINTER;
  3955.  
  3956.  
  3957. [PARAMETERS]
  3958. StringLen   Maximum string length to allocate
  3959. DefString   Default new string text
  3960.  
  3961. [RETURNS]
  3962.  
  3963. Pointer to New String and data.
  3964.  
  3965. [DESCRIPTIO]
  3966.  
  3967. This function allocates room for the specified string on the heap,
  3968. copies the string to the heap, and returns a point to the new copy.
  3969.  
  3970. There are advantages in obtaining strings from Heap Memory as opposed
  3971. to the Stack, not the least of which is the fact that the Heap is larger
  3972. and more Dynamic where the Stack has to be set at Compile Time.
  3973.  
  3974. [SEE-ALSO]
  3975.  
  3976. VStrGet
  3977. VStrDispose
  3978.  
  3979. [EXAMPLE]
  3980.  
  3981. VAR
  3982.   P : POINTER;
  3983.  
  3984. BEGIN
  3985.  
  3986.   P := VStrNew( 'This is the String' );
  3987.  
  3988.   { P now points to the String Data as well as the Memory Allocations }
  3989.  
  3990. END;
  3991.  
  3992. -*)
  3993.  
  3994. Function  VStrNew(                S             : STRING        ) : POINTER;
  3995.  
  3996.  
  3997. Var
  3998.  
  3999.   TempPtr  : PByteArray;
  4000.   AllocLen : WORD;
  4001.  
  4002. BEGIN
  4003.  
  4004.   AllocLen := Byte(S[0])+1;
  4005.  
  4006.   If MaxAvail<AllocLen Then
  4007.     VStrNew := NIL
  4008.   ELSE
  4009.   BEGIN
  4010.     GetMem( TempPtr, AllocLen );
  4011.     Move( S, TempPtr^, AllocLen );
  4012.     VStrNew := TempPtr;
  4013.   END;
  4014.  
  4015. END;
  4016.  
  4017. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4018.  
  4019. (*-
  4020.  
  4021. [FUNCTION]
  4022.  
  4023. Function  VStrGet(                StringPtr     : PString       ) : STRING;
  4024.  
  4025.  
  4026. [PARAMETERS]
  4027.  
  4028. StringPtr   String Pointer
  4029.  
  4030. [RETURNS]
  4031.  
  4032. Pascal String in Heap Memory
  4033.  
  4034. [DESCRIPTION]
  4035.  
  4036. This is the
  4037.  
  4038. There are advantages in obtaining strings from Heap Memory as opposed
  4039. to the Stack, not the least of which is the fact that the Heap is larger
  4040. and more Dynamic where the Stack has to be set at Compile Time.
  4041.  
  4042. [SEE-ALSO]
  4043.  
  4044. VStrNew
  4045. VStrDispose
  4046.  
  4047. [EXAMPLE]
  4048.  
  4049. VAR
  4050.   S : STRING;
  4051.  
  4052. BEGIN
  4053.  
  4054.   S := VStrGet( VStrNew( 'This is the String' ) );
  4055.  
  4056.   {--------------------------------------------------------------------}
  4057.   { S now contains "This is the String" from the Dynamically allocated }
  4058.   { from the Heap while the String Pointer itself also includes the    }
  4059.   { Memory Allocation associated with this String Pointer              }
  4060.   {--------------------------------------------------------------------}
  4061.  
  4062. END;
  4063.  
  4064. -*)
  4065.  
  4066. Function  VStrGet(                StringPtr     : PString       ) : STRING;
  4067.  
  4068.  
  4069. BEGIN
  4070.  
  4071.   If StringPtr=NIL Then
  4072.     VStrGet := ''
  4073.   Else
  4074.     VStrGet := StringPtr^;
  4075.  
  4076. END;
  4077.  
  4078.  
  4079. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4080.  
  4081. (*-
  4082.  
  4083. [FUNCTION]
  4084.  
  4085. Procedure VStrDispose(             PrevVStrNew : POINTER );
  4086.  
  4087. [PARAMETERS]
  4088.  
  4089. PrevVStrNew   Existing String pointer created by VStrNew
  4090.  
  4091. [RETURNS]
  4092.  
  4093. (None)
  4094.  
  4095. [DESCRIPTION]
  4096.  
  4097. This is the complementary function to VStrNew.  It will take the
  4098. VStrNew string pointer and deallocate it from the heap.  It should
  4099. be noted that all the information about the allocated memory size is
  4100. already contained with the string pointer data, thus deallocation is
  4101. completely invisible to the user.
  4102.  
  4103. [SEE-ALSO]
  4104.  
  4105. VStrNew
  4106. VStrGet
  4107.  
  4108. [EXAMPLE]
  4109.  
  4110. VAR
  4111.   P : POINTER;
  4112.  
  4113. BEGIN
  4114.  
  4115.   P := VStrNew( 'This is the String' );
  4116.   { P now points to the String Data as well as the Memory Allocations }
  4117.  
  4118.   VStrDispose( P );
  4119.  
  4120.   {-----------------------------------}
  4121.   { P now is an unassigned pointer,   }
  4122.   { all memory associated with it has }
  4123.   { been deallocated                  }
  4124.   {-----------------------------------}
  4125.  
  4126. END;
  4127.  
  4128. -*)
  4129.  
  4130. Procedure VStrDispose(            PrevNewString : PString       );
  4131.  
  4132. BEGIN
  4133.  
  4134.   If PrevNewString<>NIL Then
  4135.     FreeMem( PrevNewString, Byte(PrevNewString^[0])+1 );
  4136.  
  4137. END;
  4138.  
  4139. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4140.  
  4141. (*-
  4142.  
  4143. [FUNCTION]
  4144.  
  4145. [PARAMETERS]
  4146.  
  4147. [RETURNS]
  4148.  
  4149. [DESCRIPTION]
  4150.  
  4151. [SEE-ALSO]
  4152.  
  4153. [EXAMPLE]
  4154.  
  4155. -*)
  4156.  
  4157. Function  VStrListNew(            Flags          : WORD;
  4158.                                   NumItems       : INTEGER;
  4159.                                   ItemLen        : WORD         ) : PStrList;
  4160.  
  4161.  
  4162. Type
  4163.  
  4164.   MyPByte = ^BYTE;
  4165.  
  4166. Var
  4167.  
  4168.   NSL      : PStrList;
  4169.   Z        : INTEGER;
  4170.  
  4171.   LLNs     : PLLStringNode;
  4172.   LLNpchar : PLLPcharNode;
  4173.  
  4174. BEGIN
  4175.  
  4176.  
  4177.   New( NSL );
  4178.  
  4179.   Case Flags of
  4180.  
  4181.     cslStrings:
  4182.     BEGIN
  4183.  
  4184.       {------------------------------------}
  4185.       { get the memory for all the strings }
  4186.       {------------------------------------}
  4187.  
  4188.       GetMem( NSL^.SL, NumItems*(ItemLen+1) );
  4189.  
  4190.       {----------------------}
  4191.       { zero out each string }
  4192.       {----------------------}
  4193.  
  4194.       For Z:=1 to NumItems Do
  4195.         MyPByte( PtrAdd( NSL^.SL, (Z-1)*(ItemLen+1) ) )^:=0;
  4196.  
  4197.     END;
  4198.  
  4199.     cslPStrings:
  4200.     BEGIN
  4201.  
  4202.       {------------------------------------------}
  4203.       { Get the memory for the array of pointers }
  4204.       {------------------------------------------}
  4205.  
  4206.       GetMem( NSL^.SL, SizeOf( POINTER ) * NumItems );
  4207.  
  4208.       {-------------------------------------}
  4209.       { Now get the memory for each pointer }
  4210.       {-------------------------------------}
  4211.  
  4212.       For Z := 1 to NumItems Do
  4213.       BEGIN
  4214.         GetMem( PPStrings( NSL^.SL )^[Z], ItemLen+1 );
  4215.  
  4216.         PPStrings( NSL^.SL )^[Z]^ := '';
  4217.       END;
  4218.  
  4219.     END;
  4220.  
  4221.  
  4222.     cslLLStrings:
  4223.     BEGIN
  4224.  
  4225.       New( LLNs );
  4226.  
  4227.       NSL^.SL := LLNs;
  4228.  
  4229.       For Z := 2 to NumItems Do
  4230.       BEGIN
  4231.  
  4232.         New( LLNs^.Next );
  4233.  
  4234.         LLNs^.Next^.S := '';
  4235.  
  4236.         LLNs := LLNs^.Next;
  4237.  
  4238.       END;
  4239.  
  4240.       LLNs^.Next := NIL;
  4241.  
  4242.     END;
  4243.  
  4244.  
  4245.   {$IFNDEF NOSTRINGS}
  4246.  
  4247.     cslPChars:
  4248.     BEGIN
  4249.  
  4250.       {------------------------------------------}
  4251.       { Get the memory for the array of pointers }
  4252.       {------------------------------------------}
  4253.  
  4254.       GetMem( NSL^.SL, SizeOf( POINTER ) * NumItems );
  4255.  
  4256.       {-------------------------------------}
  4257.       { Now get the memory for each pointer }
  4258.       {-------------------------------------}
  4259.  
  4260.       For Z := 1 to NumItems Do
  4261.       BEGIN
  4262.  
  4263.         GetMem( PPointers( NSL^.SL )^[Z], ItemLen+1 );
  4264.  
  4265.         StrPCopy( PPChars( NSL^.SL )^[Z], '' );
  4266.  
  4267. {        PPChars( NSL^.SL )^[Z] := '';  }
  4268.  
  4269.       END;
  4270.  
  4271.     END;
  4272.  
  4273.     cslLLPChars:
  4274.     BEGIN
  4275.  
  4276.       New( LLNpchar );
  4277.  
  4278.       GetMem( LLNpchar^.S, ItemLen+1 );
  4279.  
  4280.       StrPCopy( LLNpchar^.S, '' );
  4281.  
  4282.       NSL^.SL := LLNpchar;
  4283.  
  4284.       For Z := 2 to NumItems Do
  4285.       BEGIN
  4286.  
  4287.         New( LLNpchar^.Next );
  4288.  
  4289.         GetMem( LLNpchar^.Next^.S, ItemLen+1 );
  4290.  
  4291.         StrPCopy( LLNpchar^.Next^.S, '' );
  4292.  
  4293.         LLNpchar := LLNpchar^.Next;
  4294.  
  4295.       END;
  4296.  
  4297.       LLNpchar^.NEXT := NIL;
  4298.  
  4299.     END;
  4300.  
  4301.   {$ENDIF}
  4302.  
  4303.   END; { case statement }
  4304.  
  4305.   {-----------------------------------------}
  4306.   { Fill in the rest of the New String List }
  4307.   {-----------------------------------------}
  4308.  
  4309.   NSL^.Flags   := Flags;
  4310.   NSL^.Items   := NumItems;
  4311.   NSL^.ItemLen := ItemLen;
  4312.  
  4313.   VStrListNew  := NSL;
  4314.  
  4315.  
  4316. END; { function VStrListNew }
  4317.  
  4318.  
  4319. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4320.  
  4321. Procedure VStrListDispose(        SL             : PStrList     ) ;
  4322.  
  4323. Var
  4324.  
  4325.   Z            : INTEGER;
  4326.   LLNs         : PLLStringNode;
  4327.   nextLLNs     : PLLStringNode;
  4328.   LLNpchar     : PLLPCharNode;
  4329.   nextLLNPchar : PLLPCharNode;
  4330.  
  4331.  
  4332. BEGIN
  4333.  
  4334.   Case SL^.Flags of
  4335.  
  4336.     cslStrings:
  4337.     BEGIN
  4338.  
  4339.       FreeMem( SL^.SL, SL^.Items*(SL^.ItemLen+1) );
  4340.  
  4341.     END;
  4342.  
  4343.     cslPStrings:
  4344.     BEGIN
  4345.  
  4346.       {---------------------------------------}
  4347.       { First free the memory for each string }
  4348.       {---------------------------------------}
  4349.  
  4350.       For Z := 1 to SL^.Items Do
  4351.         FreeMem( PPStrings( SL^.SL )^[Z], SL^.ItemLen+1 );
  4352.  
  4353.       {-------------------------------------------}
  4354.       { Free the memory for the array of pointers }
  4355.       {-------------------------------------------}
  4356.  
  4357.       FreeMem( SL^.SL, SizeOf( POINTER ) * SL^.Items );
  4358.  
  4359.     END;
  4360.  
  4361.  
  4362.     cslLLStrings:
  4363.     BEGIN
  4364.  
  4365.       LLNs := SL^.SL;
  4366.  
  4367.       For Z := 1 to SL^.Items Do
  4368.       BEGIN
  4369.  
  4370.         nextLLNs := LLNs^.Next;
  4371.  
  4372.         Dispose( LLNs );
  4373.  
  4374.         LLNs := nextLLNs;
  4375.  
  4376.       END;
  4377.  
  4378.     END;
  4379.  
  4380.  
  4381.     cslPChars:
  4382.     BEGIN
  4383.  
  4384.  
  4385.       {---------------------------------------}
  4386.       { First free the memory for each string }
  4387.       {---------------------------------------}
  4388.  
  4389.       For Z := 1 to SL^.Items Do
  4390.         FreeMem( PPChars( SL^.SL )^[Z], SL^.ItemLen+1 );
  4391.  
  4392.       {-------------------------------------------}
  4393.       { Free the memory for the array of pointers }
  4394.       {-------------------------------------------}
  4395.  
  4396.       Freemem( SL^.SL, SizeOf( POINTER ) * SL^.Items );
  4397.  
  4398.     END;
  4399.  
  4400.     cslLLPChars:
  4401.     BEGIN
  4402.  
  4403.       LLNpchar := SL^.SL;
  4404.  
  4405.       For Z := 1 to SL^.Items Do
  4406.       BEGIN
  4407.  
  4408.         nextLLNpchar := LLNpchar^.Next;
  4409.  
  4410.         FreeMem( LLNpchar^.s, SL^.ItemLen+1 );
  4411.  
  4412.         Dispose( LLNpchar );
  4413.  
  4414.         LLNpchar := nextLLNpchar;
  4415.  
  4416.       END;
  4417.  
  4418.  
  4419.     END;
  4420.  
  4421.   END; { case statement }
  4422.  
  4423.   Dispose( SL );
  4424.  
  4425. END;
  4426.  
  4427. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4428.  
  4429. Function  VStrListGetPtr(         StrList        : PStrList;
  4430.                                   StrNum         : INTEGER      ) : PSTRING;
  4431.  
  4432.  
  4433. Var
  4434.  
  4435.   Z        : INTEGER;
  4436.   LLNs     : PLLStringNode;
  4437.   LLNpchar : PLLPCharNode;
  4438.  
  4439.  
  4440. BEGIN
  4441.  
  4442.   Case StrList^.Flags of
  4443.  
  4444.     cslStrings:
  4445.     BEGIN
  4446.  
  4447.       VStrListGetPtr := PtrAdd( StrList^.SL,
  4448.                                 (StrNum-1)*(StrList^.ItemLen+1) );
  4449.  
  4450.     END;
  4451.  
  4452.     cslPStrings:
  4453.     BEGIN
  4454.  
  4455.       VStrListGetPtr := PPStrings( StrList^.SL )^[StrNum];
  4456.  
  4457.     END;
  4458.  
  4459.  
  4460.     cslLLStrings:
  4461.     BEGIN
  4462.  
  4463.       Z    := 1;
  4464.  
  4465.       LLNs := StrList^.SL;
  4466.  
  4467.       While (Z<>StrNum) and (LLNS^.Next<>NIL) Do
  4468.       BEGIN
  4469.         Inc( Z );
  4470.         LLNs := LLNs^.Next;
  4471.       END;
  4472.  
  4473.       If Z=StrNum Then
  4474.         VStrListGetPtr := @LLNs^.S
  4475.       ELSE
  4476.         VStrListGetPtr := NIL;
  4477.  
  4478.     END;
  4479.  
  4480.  
  4481.     cslPChars:
  4482.     BEGIN
  4483.  
  4484.       VStrListGetPtr := pointer( PPChars( StrList^.SL )^[StrNum] );
  4485.  
  4486.     END;
  4487.  
  4488.     cslLLPChars:
  4489.     BEGIN
  4490.  
  4491.       Z    := 1;
  4492.  
  4493.       LLNpchar := StrList^.SL;
  4494.  
  4495.       While (Z<>StrNum) and (LLNpchar^.Next<>NIL) Do
  4496.       BEGIN
  4497.         Inc( Z );
  4498.         LLNpchar := LLNpchar^.Next;
  4499.       END;
  4500.  
  4501.  
  4502.       If Z=StrNum Then
  4503.         VStrListGetPtr := pointer( LLNpchar^.S )
  4504.       ELSE
  4505.         VStrListGetPtr := NIL;
  4506.  
  4507.     END;
  4508.  
  4509.   END; { case statement }
  4510.  
  4511.  
  4512. END;
  4513.  
  4514.  
  4515. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4516.  
  4517. Function  VStrListGetStr(         StrList        : PStrList;
  4518.                                   StrNum         : INTEGER      ) : STRING;
  4519.  
  4520. Var
  4521.  
  4522.   Z        : INTEGER;
  4523.   LLNs     : PLLStringNode;
  4524.   LLNpchar : PLLPCharNode;
  4525.  
  4526. BEGIN
  4527.  
  4528.  
  4529.   Case StrList^.Flags of
  4530.  
  4531.     cslStrings:
  4532.     BEGIN
  4533.  
  4534.       VStrListGetStr := PString( PtrAdd( StrList^.SL,
  4535.                                          (StrNum-1)*
  4536.                                             (StrList^.ItemLen+1) ) )^;
  4537.  
  4538.     END;
  4539.  
  4540.     cslPStrings:
  4541.     BEGIN
  4542.  
  4543.       VStrListGetStr := PString( PPStrings( StrList^.SL )^[StrNum] )^;
  4544.  
  4545.     END;
  4546.  
  4547.  
  4548.     cslLLStrings:
  4549.     BEGIN
  4550.  
  4551.       Z    := 1;
  4552.  
  4553.       LLNs := StrList^.SL;
  4554.  
  4555.       While (Z<>StrNum) and (LLNS^.Next<>NIL) Do
  4556.       BEGIN
  4557.         Inc( Z );
  4558.         LLNs := LLNs^.Next;
  4559.       END;
  4560.  
  4561.       If Z=StrNum Then
  4562.         VStrListGetStr := LLNs^.S
  4563.       ELSE
  4564.         VStrListGetStr := '';
  4565.  
  4566.     END;
  4567.  
  4568.   {$IFNDEF NOSTRINGS}
  4569.  
  4570.     cslPChars:
  4571.     BEGIN
  4572.  
  4573.       VStrListGetStr := StrPas( PPChars( StrList^.SL )^[StrNum] );
  4574.  
  4575.     END;
  4576.  
  4577.     cslLLPChars:
  4578.     BEGIN
  4579.  
  4580.       Z    := 1;
  4581.  
  4582.       LLNpchar := StrList^.SL;
  4583.  
  4584.       While (Z<>StrNum) and (LLNpchar^.Next<>NIL) Do
  4585.       BEGIN
  4586.         Inc( Z );
  4587.         LLNpchar := LLNpchar^.Next;
  4588.       END;
  4589.  
  4590.  
  4591.       If Z=StrNum Then
  4592.         VStrListGetStr := StrPas( LLNpchar^.S )
  4593.       ELSE
  4594.         VStrListGetStr := '';
  4595.  
  4596.  
  4597.  
  4598.     END;
  4599.  
  4600.   {$ENDIF}
  4601.  
  4602.   END; { case statement }
  4603.  
  4604.  
  4605. END;
  4606.  
  4607.  
  4608. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4609.  
  4610. Procedure VStrListPutStr(         StrList        : PStrList;
  4611.                                   StrNum         : INTEGER;
  4612.                                   StrToPut       : STRING       );
  4613.  
  4614.  
  4615. Var
  4616.  
  4617.   Z        : INTEGER;
  4618.   LLNs     : PLLStringNode;
  4619.   LLNpchar : PLLPCharNode;
  4620.  
  4621. BEGIN
  4622.  
  4623.   Case StrList^.Flags of
  4624.  
  4625.     cslStrings:
  4626.     BEGIN
  4627.  
  4628.       PString( PtrAdd( StrList^.SL,
  4629.                        (StrNum-1)*
  4630.                          (StrList^.ItemLen+1) ) )^ := StrToPut;
  4631.  
  4632.     END;
  4633.  
  4634.     cslPStrings:
  4635.     BEGIN
  4636.  
  4637.       PString( PPStrings( StrList^.SL )^[StrNum] )^ := StrToPut;
  4638.  
  4639.     END;
  4640.  
  4641.  
  4642.     cslLLStrings:
  4643.     BEGIN
  4644.  
  4645.       Z    := 1;
  4646.  
  4647.       LLNs := StrList^.SL;
  4648.  
  4649.       While (Z<>StrNum) and (LLNS^.Next<>NIL) Do
  4650.       BEGIN
  4651.         Inc( Z );
  4652.         LLNs := LLNs^.Next;
  4653.       END;
  4654.  
  4655.       If Z=StrNum Then
  4656.         LLNs^.S := StrToPut;
  4657.  
  4658.     END;
  4659.  
  4660.  
  4661.   {$IFNDEF NOSTRINGS}
  4662.  
  4663.     cslPChars:
  4664.     BEGIN
  4665.  
  4666.       StrPCopy( PPChars( StrList^.SL )^[StrNum], StrToPut );
  4667.  
  4668.     END;
  4669.  
  4670.     cslLLPChars:
  4671.     BEGIN
  4672.  
  4673.       Z    := 1;
  4674.  
  4675.       LLNpchar := StrList^.SL;
  4676.  
  4677.       While (Z<>StrNum) and (LLNpchar^.Next<>NIL) Do
  4678.       BEGIN
  4679.         Inc( Z );
  4680.         LLNpchar := LLNpchar^.Next;
  4681.       END;
  4682.  
  4683.       If Z=StrNum Then
  4684.         StrPCopy(  LLNpchar^.S, StrToPut );
  4685.  
  4686.  
  4687.     END;
  4688.  
  4689.   {$ENDIF}
  4690.  
  4691.   END; { case statement }
  4692.  
  4693.  
  4694.  
  4695. END;
  4696.  
  4697.  
  4698. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4699.  
  4700. Function  VStrListGetPChar(       StrList        : PStrList;
  4701.                                   StrNum         : INTEGER      ) : PChar;
  4702.  
  4703. Var
  4704.  
  4705.   Z        : INTEGER;
  4706.   LLNpchar : PLLPCharNode;
  4707.  
  4708.  
  4709. BEGIN
  4710.  
  4711.  
  4712.   Case StrList^.Flags of
  4713.  
  4714.     cslStrings:
  4715.     BEGIN
  4716.  
  4717.     END;
  4718.  
  4719.     cslPStrings:
  4720.     BEGIN
  4721.  
  4722.     END;
  4723.  
  4724.  
  4725.     cslLLStrings:
  4726.     BEGIN
  4727.  
  4728.     END;
  4729.  
  4730.  
  4731.     cslPChars:
  4732.     BEGIN
  4733.  
  4734.       VStrListGetPChar := PPChars( StrList^.SL )^[StrNum];
  4735.  
  4736.     END;
  4737.  
  4738.     cslLLPChars:
  4739.     BEGIN
  4740.  
  4741.       Z    := 1;
  4742.  
  4743.       LLNpchar := StrList^.SL;
  4744.  
  4745.       While (Z<>StrNum) and (LLNpchar^.Next<>NIL) Do
  4746.       BEGIN
  4747.         Inc( Z );
  4748.         LLNpchar := LLNpchar^.Next;
  4749.       END;
  4750.  
  4751.  
  4752.       If Z=StrNum Then
  4753.         VStrListgetPchar := LLNPchar^.s
  4754.       ELSE
  4755.         VStrListGetPchar := NIL;
  4756.  
  4757.     END;
  4758.  
  4759.  
  4760.   END; { case statement }
  4761.  
  4762. END;
  4763.  
  4764.  
  4765. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4766.  
  4767. Procedure VStrListPutPChar(       StrList        : PStrList;
  4768.                                   StrNum         : INTEGER;
  4769.                                   PCharToPut     : PChar        );
  4770.  
  4771.  
  4772. Var
  4773.  
  4774.   Z        : INTEGER;
  4775.   LLNs     : PLLStringNode;
  4776.   LLNpchar : PLLPCharNode;
  4777.  
  4778. BEGIN
  4779.  
  4780. {$IFNDEF NOSTRINGS}
  4781.  
  4782.   Case StrList^.Flags of
  4783.  
  4784.     cslStrings:
  4785.     BEGIN
  4786.  
  4787.       PString( PtrAdd( StrList^.SL,
  4788.                        (StrNum-1)*
  4789.                          (StrList^.ItemLen+1) ) )^ := StrPas( PCharToPut );
  4790.  
  4791.     END;
  4792.  
  4793.     cslPStrings:
  4794.     BEGIN
  4795.  
  4796.       PString( PPStrings( StrList^.SL )^[StrNum] )^ := StrPas( PCharToPut );
  4797.  
  4798.     END;
  4799.  
  4800.  
  4801.     cslLLStrings:
  4802.     BEGIN
  4803.  
  4804.       Z    := 1;
  4805.  
  4806.       LLNs := StrList^.SL;
  4807.  
  4808.       While (Z<>StrNum) and (LLNS^.Next<>NIL) Do
  4809.       BEGIN
  4810.         Inc( Z );
  4811.         LLNs := LLNs^.Next;
  4812.       END;
  4813.  
  4814.       If Z=StrNum Then
  4815.         LLNs^.S := StrPas( PCharToPut );
  4816.  
  4817.     END;
  4818.  
  4819.  
  4820.     cslPChars:
  4821.     BEGIN
  4822.  
  4823.       StrCopy( PPChars( StrList^.SL )^[StrNum], PCharToPut );
  4824.  
  4825.     END;
  4826.  
  4827.     cslLLPChars:
  4828.     BEGIN
  4829.  
  4830.       Z    := 1;
  4831.  
  4832.       LLNpchar := StrList^.SL;
  4833.  
  4834.       While (Z<>StrNum) and (LLNpchar^.Next<>NIL) Do
  4835.       BEGIN
  4836.         Inc( Z );
  4837.         LLNpchar := LLNpchar^.Next;
  4838.       END;
  4839.  
  4840.       If Z=StrNum Then
  4841.         StrCopy( LLNpchar^.S, PCharToPut );
  4842.  
  4843.  
  4844.     END;
  4845.  
  4846.  
  4847.   END; { case statement }
  4848.  
  4849.  
  4850. {$ENDIF}
  4851.  
  4852. END;
  4853.  
  4854.  
  4855. (*-
  4856.  
  4857. [FUNCTION]
  4858.  
  4859. Function ColorFromString(         S              : STRING       ) : BYTE;
  4860.  
  4861. [PARAMETERS]
  4862.  
  4863. S           Text color, as a string.  IE: "RED"
  4864.  
  4865. [RETURNS]
  4866.  
  4867. Numeric Color Value
  4868.  
  4869. [DESCRIPTION]
  4870.  
  4871. This function converts a Text String Color Name into a Color Value.
  4872. This function is NOT Case Sensitive.
  4873.  
  4874. [SEE-ALSO]
  4875.  
  4876. [EXAMPLE]
  4877.  
  4878. CONST
  4879.   ColorNames = ARRAY[0..7] of STRING =
  4880.                ( 'BLACK','WHITE','BLUE','GREEN',
  4881.                  'RED','YELLOW','CYAN','MAGENTA' );
  4882. VAR
  4883.   I : INTEGER;
  4884.  
  4885. BEGIN
  4886.  
  4887.   Textbackground( WHITE );
  4888.  
  4889.   For i := 0 to 7 Do
  4890.   BEGIN
  4891.     TextColor( WColorFromString( ColorNames[i] ) );
  4892.     WriteLn( ColorNames[i] );
  4893.   END;  { For i }
  4894.  
  4895. END;
  4896.  
  4897. -*)
  4898.  
  4899. Function ColorFromString(        S              : STRING       ) : BYTE;
  4900.  
  4901. Var
  4902.  
  4903.   Z     : INTEGER;
  4904.   Found : BOOLEAN;
  4905.  
  4906. Const
  4907.  
  4908.   Colors : Array[0..15] of STRING[15] = ( 'BLACK',
  4909.                                           'BLUE',
  4910.                                           'GREEN',
  4911.                                           'CYAN',
  4912.                                           'RED',
  4913.                                           'MAGENTA',
  4914.                                           'BROWN',
  4915.                                           'LIGHTGRAY',
  4916.                                           'DARKGRAY',
  4917.                                           'LIGHTBLUE',
  4918.                                           'LIGHTGREEN',
  4919.                                           'LIGHTCYAN',
  4920.                                           'LIGHTRED',
  4921.                                           'LIGHTMAGENTA',
  4922.                                           'YELLOW',
  4923.                                           'WHITE'          );
  4924.  
  4925. BEGIN
  4926.  
  4927.   S := UpperString(S);
  4928.   Z := 0;
  4929.  
  4930.   REPEAT
  4931.  
  4932.     Found := Pos(Colors[Z], S) <> 0;
  4933.  
  4934.     If NOT Found Then
  4935.       Inc(Z);
  4936.  
  4937.   UNTIL Found OR (Z > 15);
  4938.  
  4939.   If Found Then
  4940.     ColorFromString := Z
  4941.   Else
  4942.     ColorFromString := 7;
  4943.  
  4944. END; { Of ColorFromString }
  4945.  
  4946.  
  4947.  
  4948. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4949. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4950. {ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ}
  4951.  
  4952.  
  4953. BEGIN
  4954.  
  4955.  
  4956. END.